Mercurial > hg > bitcoin
changeset 1186:69323e942d0e draft
Merge branch 'master' of https://github.com/bitcoin/bitcoin
author | Wladimir J. van der Laan <laanwj@gmail.com> |
---|---|
date | Fri, 15 Jul 2011 16:08:38 +0200 |
parents | dd486efef3cf (current diff) e893fa2204e6 (diff) |
children | 5c41b03dc484 58653a806684 |
files | bitcoin-qt.pro src/bitcoinrpc.cpp src/cryptopp/cpu.cpp src/db.cpp src/db.h src/init.cpp src/key.h src/keystore.cpp src/keystore.h src/main.cpp src/main.h src/net.cpp src/net.h src/qt/addresstablemodel.cpp src/script.cpp src/script.h src/serialize.h src/util.cpp src/util.h src/wallet.cpp src/wallet.h |
diffstat | 42 files changed, 2268 insertions(+), 682 deletions(-) [+] |
line wrap: on
line diff
--- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -83,7 +83,8 @@ src/bitcoinrpc.h \ src/qt/overviewpage.h \ src/qt/csvmodelwriter.h \ - src/qt/qtwin.h + src/qt/qtwin.h \ + src/crypter.h SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/transactiontablemodel.cpp \ src/qt/addresstablemodel.cpp \ @@ -122,7 +123,8 @@ src/bitcoinrpc.cpp \ src/qt/overviewpage.cpp \ src/qt/csvmodelwriter.cpp \ - src/qt/qtwin.cpp + src/qt/qtwin.cpp \ + src/crypter.cpp RESOURCES += \ src/qt/bitcoin.qrc
--- a/contrib/Bitcoin.app/Contents/Info.plist +++ b/contrib/Bitcoin.app/Contents/Info.plist @@ -17,11 +17,11 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> - <string>0.3.24</string> + <string>0.3.25</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>324</string> + <string>325</string> <key>LSMinimumSystemVersion</key> <string>10.5</string> <key>CFBundleIconFile</key>
--- a/doc/README +++ b/doc/README @@ -1,4 +1,4 @@ -Bitcoin 0.3.24 BETA +Bitcoin 0.3.25 BETA Copyright (c) 2009-2011 Bitcoin Developers Distributed under the MIT/X11 software license, see the accompanying @@ -24,6 +24,49 @@ bin/64/bitcoin (GUI, 64-bit) bin/64/bitcoind (headless, 64-bit) + +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, chose "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 +password 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 you 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 documentation at the bitcoin wiki: https://en.bitcoin.it/wiki/Main_Page
--- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin 0.3.24 BETA +Bitcoin 0.3.25 BETA Copyright (c) 2009-2011 Bitcoin Developers Distributed under the MIT/X11 software license, see the accompanying
--- a/locale/pl/LC_MESSAGES/bitcoin.po +++ b/locale/pl/LC_MESSAGES/bitcoin.po @@ -2,7 +2,7 @@ msgstr "" "Project-Id-Version: Bitcoin\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-06-28 20:11+0100\n" +"POT-Creation-Date: 2011-07-14 18:55+0100\n" "PO-Revision-Date: \n" "Last-Translator: Dawid Spiechowicz <spiechu@gmail.com>\n" "Language-Team: Spiechu <spiechu@gmail.com>\n" @@ -18,7 +18,7 @@ "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" "X-Poedit-SearchPath-0: ../../..\n" -#: ../../../src/net.cpp:1590 +#: ../../../src/net.cpp:1615 #, c-format msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." msgstr "Nie można powiązać z portem %d tego komputera. Prawdopodobnie program Bitcoin jest już uruchomiony." @@ -188,29 +188,37 @@ msgid "Error loading blkindex.dat \n" msgstr "Błąd ładowania blkindex.dat \n" -#: ../../../src/init.cpp:391 +#: ../../../src/init.cpp:394 +msgid "Error loading wallet.dat: Wallet corrupted \n" +msgstr "Błąd ładowania wallet.dat: Portfel uszkodzony \n" + +#: ../../../src/init.cpp:396 +msgid "Error loading wallet.dat: Wallet requires newer version of Bitcoin \n" +msgstr "Błąd ładowania wallet.dat: Portfel wymaga nowszej wersji Bitcoin \n" + +#: ../../../src/init.cpp:398 msgid "Error loading wallet.dat \n" msgstr "Błąd ładowania wallet.dat \n" -#: ../../../src/init.cpp:481 +#: ../../../src/init.cpp:488 msgid "Invalid -proxy address" msgstr "Niewłaściwy adres -proxy" -#: ../../../src/init.cpp:504 +#: ../../../src/init.cpp:513 msgid "Invalid amount for -paytxfee=<amount>" msgstr "Nieprawidłowa kwota w -paytxfee=<amount>" -#: ../../../src/init.cpp:508 +#: ../../../src/init.cpp:517 msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." msgstr "Ostrzeżenie: ustawienie -paytxfee jest bardzo wysokie. To jest prowizja transakcji, którą zapłacisz jeżeli wyślesz transakcję." -#: ../../../src/rpc.cpp:1822 -#: ../../../src/rpc.cpp:1824 +#: ../../../src/rpc.cpp:2100 +#: ../../../src/rpc.cpp:2102 #, c-format msgid "To use the %s option" msgstr "Użycie opcji %s" -#: ../../../src/rpc.cpp:1826 +#: ../../../src/rpc.cpp:2104 #, c-format msgid "" "Warning: %s, you must set rpcpassword=<password>\n" @@ -221,7 +229,7 @@ "w pliku konfiguracyjnym: %s\n" "Jeżeli plik nie istnieje, utwórz go z uprawnieniami tylko do odczytu dla właściciela.\n" -#: ../../../src/rpc.cpp:1994 +#: ../../../src/rpc.cpp:2277 #, c-format msgid "" "You must set rpcpassword=<password> in the configuration file:\n" @@ -232,11 +240,11 @@ "%s\n" "Jeżeli plik nie istnieje, utwórz go z uprawnieniami tylko do odczytu dla właściciela." -#: ../../../src/util.cpp:874 +#: ../../../src/util.cpp:869 msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." msgstr "Ostrzeżenie: Sprawdź czy ustawienia daty i czasu komputera są prawidłowe. Jeżeli zegar jest źle ustawiony, Bitcoin nie będzie poprawnie działał." -#: ../../../src/util.cpp:908 +#: ../../../src/util.cpp:903 msgid "beta" msgstr "beta" @@ -245,104 +253,190 @@ msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" msgstr "Ta transakcja jest poza limitem wielkości. W dalszym ciągu możesz wysłać ją z prowizją %s, która dotrze do węzłów przetwarzających twoją transakcję i pomoże utrzymać sieć. Chcesz zapłacić prowizję?" -#: ../../../src/ui.cpp:316 +#: ../../../src/ui.cpp:259 +#: ../../../src/ui.cpp:1246 +msgid "Enter the current passphrase to the wallet." +msgstr "Wpisz obecne hasło do portfela." + +#: ../../../src/ui.cpp:260 +#: ../../../src/ui.cpp:1182 +#: ../../../src/ui.cpp:1199 +#: ../../../src/ui.cpp:1247 +#: ../../../src/ui.cpp:1273 +#: ../../../src/ui.cpp:1293 +msgid "Passphrase" +msgstr "Hasło" + +#: ../../../src/ui.cpp:266 +msgid "Please supply the current wallet decryption passphrase." +msgstr "Proszę dostarczyć hasło do odszyfrowania portfela." + +#: ../../../src/ui.cpp:274 +#: ../../../src/ui.cpp:1258 +#: ../../../src/ui.cpp:1315 +msgid "The passphrase entered for the wallet decryption was incorrect." +msgstr "Wpisane hasło do odszyfrowania portfela jest nieprawidłowe." + +#: ../../../src/ui.cpp:351 msgid "Status" msgstr "Status" -#: ../../../src/ui.cpp:317 +#: ../../../src/ui.cpp:352 msgid "Date" msgstr "Data" -#: ../../../src/ui.cpp:318 +#: ../../../src/ui.cpp:353 msgid "Description" msgstr "Opis" -#: ../../../src/ui.cpp:319 +#: ../../../src/ui.cpp:354 msgid "Debit" msgstr "Obciążenie" -#: ../../../src/ui.cpp:320 +#: ../../../src/ui.cpp:355 msgid "Credit" msgstr "Suma" -#: ../../../src/ui.cpp:526 +#: ../../../src/ui.cpp:566 #, c-format msgid "Open for %d blocks" msgstr "Otwórz na %d bloków" -#: ../../../src/ui.cpp:528 +#: ../../../src/ui.cpp:568 #, c-format msgid "Open until %s" msgstr "Otwarte dopóki %s" -#: ../../../src/ui.cpp:534 +#: ../../../src/ui.cpp:574 #, c-format msgid "%d/offline?" msgstr "%d/offline?" -#: ../../../src/ui.cpp:536 +#: ../../../src/ui.cpp:576 #, c-format msgid "%d/unconfirmed" msgstr "%d/niepotwierdzono" -#: ../../../src/ui.cpp:538 +#: ../../../src/ui.cpp:578 #, c-format msgid "%d confirmations" msgstr "%d potwierdzeń" -#: ../../../src/ui.cpp:623 +#: ../../../src/ui.cpp:663 msgid "Generated" msgstr "Wygenerowano" -#: ../../../src/ui.cpp:631 +#: ../../../src/ui.cpp:671 #, c-format msgid "Generated (%s matures in %d more blocks)" msgstr "Wygenerowano (%s dojrzałych w %d więcej bloków)" -#: ../../../src/ui.cpp:635 +#: ../../../src/ui.cpp:675 msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" msgstr "Wygenerowano - Ostrzeżenie: Ten blok nie został otrzymany przez żaden inny węzeł i prawdopodobnie nie zostanie zaakceptowany!" -#: ../../../src/ui.cpp:639 +#: ../../../src/ui.cpp:679 msgid "Generated (not accepted)" msgstr "Wygenerowano (nie zaakceptowano)" -#: ../../../src/ui.cpp:649 +#: ../../../src/ui.cpp:689 msgid "From: " msgstr "Od:" -#: ../../../src/ui.cpp:673 +#: ../../../src/ui.cpp:713 msgid "Received with: " msgstr "Otrzymano z:" -#: ../../../src/ui.cpp:719 +#: ../../../src/ui.cpp:759 msgid "Payment to yourself" msgstr "Płatność dla siebie samego" -#: ../../../src/ui.cpp:753 +#: ../../../src/ui.cpp:793 msgid "To: " msgstr "Do:" -#: ../../../src/ui.cpp:1068 +#: ../../../src/ui.cpp:1108 msgid " Generating" msgstr " Generowanie" -#: ../../../src/ui.cpp:1070 +#: ../../../src/ui.cpp:1110 msgid "(not connected)" msgstr "(nie połączony)" -#: ../../../src/ui.cpp:1073 +#: ../../../src/ui.cpp:1113 #, c-format msgid " %d connections %d blocks %d transactions" msgstr " %d połączeń %d bloków %d transakcji" -#: ../../../src/ui.cpp:1178 -#: ../../../src/ui.cpp:2571 +#: ../../../src/ui.cpp:1170 +msgid "Wallet already encrypted." +msgstr "Portfel już zaszyfrowany." + +#: ../../../src/ui.cpp:1181 +msgid "" +"Enter the new passphrase to the wallet.\n" +"Please use a passphrase of 10 or more random characters, or eight or more words." +msgstr "" +"Wpisz nowe hasło dla portfela.\n" +"Proszę użyć hasła składającego się z 10 lub więcej losowych znaków albo ośmiu lub więcej słów." + +#: ../../../src/ui.cpp:1188 +#: ../../../src/ui.cpp:1281 +msgid "Error: The supplied passphrase was too short." +msgstr "Błąd: Dostarczone hasło jest za krótkie." + +#: ../../../src/ui.cpp:1192 +msgid "" +"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\n" +"Are you sure you wish to encrypt your wallet?" +msgstr "" +"OSTRZEŻENIE: Jeżeli zaszyfrujesz swój portfel i zgubisz hasło, STRACISZ WSZYSTKIE SWOJE BITCOINY!\n" +"Czy jesteś pewny, że chcesz zaszyfrować swój portfel?" + +#: ../../../src/ui.cpp:1198 +msgid "Please re-enter your new wallet passphrase." +msgstr "Proszę powtórzyć nowe hasło do portfela." + +#: ../../../src/ui.cpp:1207 +#: ../../../src/ui.cpp:1303 +msgid "Error: the supplied passphrases didn't match." +msgstr "Błąd: dostarczone hasła się nie zgadzają." + +#: ../../../src/ui.cpp:1217 +msgid "Wallet encryption failed." +msgstr "Szyfrowanie portfela nie powiodło się." + +#: ../../../src/ui.cpp:1224 +msgid "" +"Wallet Encrypted.\n" +"Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer." +msgstr "" +"Portfel zaszyfrowany.\n" +"Pamiętaj, że zaszyfrowanie portfela nie chroni w pełni twoich bitcoinów przed kradzieżą przeprowadzoną przez złośliwe oprogramowanie infekujące twój komputer." + +#: ../../../src/ui.cpp:1235 +msgid "Wallet is unencrypted, please encrypt it first." +msgstr "Portfel jest niezaszyfrowany, proszę najpierw zaszyfrować." + +#: ../../../src/ui.cpp:1272 +msgid "Enter the new passphrase for the wallet." +msgstr "Wprowadź nowe hasło dla portfela." + +#: ../../../src/ui.cpp:1292 +msgid "Re-enter the new passphrase for the wallet." +msgstr "Powtórnie wprowadź nowe hasło dla portfela." + +#: ../../../src/ui.cpp:1324 +msgid "Wallet Passphrase Changed." +msgstr "Hasło dla portfela zostało zmienione." + +#: ../../../src/ui.cpp:1381 +#: ../../../src/ui.cpp:2816 msgid "New Receiving Address" msgstr "Nowy Adres Odbiorczy" -#: ../../../src/ui.cpp:1179 -#: ../../../src/ui.cpp:2572 +#: ../../../src/ui.cpp:1382 +#: ../../../src/ui.cpp:2817 msgid "" "You should use a new address for each payment you receive.\n" "\n" @@ -352,248 +446,248 @@ "\n" "Etykieta" -#: ../../../src/ui.cpp:1251 +#: ../../../src/ui.cpp:1466 msgid "<b>Status:</b> " msgstr "<b>Status:</b>" -#: ../../../src/ui.cpp:1256 +#: ../../../src/ui.cpp:1471 msgid ", has not been successfully broadcast yet" msgstr ", nie został jeszcze prawidłowo rozgłoszony" -#: ../../../src/ui.cpp:1258 +#: ../../../src/ui.cpp:1473 #, c-format msgid ", broadcast through %d node" msgstr ", rozgłasza przez %d węzeł" -#: ../../../src/ui.cpp:1260 +#: ../../../src/ui.cpp:1475 #, c-format msgid ", broadcast through %d nodes" msgstr ", rozgłasza przez %d węzłów" -#: ../../../src/ui.cpp:1264 +#: ../../../src/ui.cpp:1479 msgid "<b>Date:</b> " msgstr "<b>Data:</b>" -#: ../../../src/ui.cpp:1272 +#: ../../../src/ui.cpp:1487 msgid "<b>Source:</b> Generated<br>" msgstr "<b>Źródło:</b> Wygenerowano<br>" -#: ../../../src/ui.cpp:1278 -#: ../../../src/ui.cpp:1296 +#: ../../../src/ui.cpp:1493 +#: ../../../src/ui.cpp:1511 msgid "<b>From:</b> " msgstr "<b>Od:</b>" -#: ../../../src/ui.cpp:1296 +#: ../../../src/ui.cpp:1511 msgid "unknown" msgstr "nieznany" -#: ../../../src/ui.cpp:1297 -#: ../../../src/ui.cpp:1321 -#: ../../../src/ui.cpp:1380 +#: ../../../src/ui.cpp:1512 +#: ../../../src/ui.cpp:1536 +#: ../../../src/ui.cpp:1595 msgid "<b>To:</b> " msgstr "<b>Do:</b>" -#: ../../../src/ui.cpp:1300 +#: ../../../src/ui.cpp:1515 msgid " (yours, label: " msgstr " (twoja, etykieta: " -#: ../../../src/ui.cpp:1302 +#: ../../../src/ui.cpp:1517 msgid " (yours)" msgstr " (twoja)" -#: ../../../src/ui.cpp:1339 -#: ../../../src/ui.cpp:1351 -#: ../../../src/ui.cpp:1397 -#: ../../../src/ui.cpp:1414 +#: ../../../src/ui.cpp:1554 +#: ../../../src/ui.cpp:1566 +#: ../../../src/ui.cpp:1612 +#: ../../../src/ui.cpp:1629 msgid "<b>Credit:</b> " msgstr "<b>Suma:</b>" -#: ../../../src/ui.cpp:1341 +#: ../../../src/ui.cpp:1556 #, c-format msgid "(%s matures in %d more blocks)" msgstr "(%s dojrzałych w %d więcej bloków)" -#: ../../../src/ui.cpp:1343 +#: ../../../src/ui.cpp:1558 msgid "(not accepted)" msgstr "(nie zaakceptowano)" -#: ../../../src/ui.cpp:1388 -#: ../../../src/ui.cpp:1396 -#: ../../../src/ui.cpp:1411 +#: ../../../src/ui.cpp:1603 +#: ../../../src/ui.cpp:1611 +#: ../../../src/ui.cpp:1626 msgid "<b>Debit:</b> " msgstr "<b>Obciążenie:</b>" -#: ../../../src/ui.cpp:1402 +#: ../../../src/ui.cpp:1617 msgid "<b>Transaction fee:</b> " msgstr "<b>Prowizja transakcji:</b>" -#: ../../../src/ui.cpp:1418 +#: ../../../src/ui.cpp:1633 msgid "<b>Net amount:</b> " msgstr "<b>Kwota netto:</b>" -#: ../../../src/ui.cpp:1425 +#: ../../../src/ui.cpp:1640 msgid "Message:" msgstr "Wiadomość:" -#: ../../../src/ui.cpp:1427 +#: ../../../src/ui.cpp:1642 msgid "Comment:" msgstr "Komentarz:" -#: ../../../src/ui.cpp:1430 +#: ../../../src/ui.cpp:1645 msgid "Generated coins must wait 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." msgstr "Wygenerowane monety muszą poczekać 120 bloków zanim mogą zostać wydane. Gdy wygenerowałeś ten blok, został rozgłoszony do sieci z przeznaczeniem do dodania do łańcucha bloków. Jeżeli nie uda się dodać bloku do łańcucha, zostanie oznaczony jako \"nie zaakceptowany\" i nie będzie mógł zostać wydany. Sporadycznie dzieje się tak jeżeli inny węzeł wygeneruje blok nie dalej niż kilka sekund od ciebie." -#: ../../../src/ui.cpp:1610 +#: ../../../src/ui.cpp:1825 msgid "Cannot write autostart/bitcoin.desktop file" msgstr "Nie mogę zapisać pliku autostart/bitcoin.desktop" -#: ../../../src/ui.cpp:1646 +#: ../../../src/ui.cpp:1861 msgid "Main" msgstr "Główne" -#: ../../../src/ui.cpp:1656 +#: ../../../src/ui.cpp:1871 msgid "&Start Bitcoin on window system startup" msgstr "&Uruchom Bitcoin przy starcie systemu" -#: ../../../src/ui.cpp:1663 +#: ../../../src/ui.cpp:1878 msgid "&Minimize on close" msgstr "&Minimalizuj przy zamknięciu" -#: ../../../src/ui.cpp:1805 +#: ../../../src/ui.cpp:2020 #, c-format msgid "version %s" msgstr "wersja %s" -#: ../../../src/ui.cpp:1928 +#: ../../../src/ui.cpp:2143 msgid "Error in amount " msgstr "Nieprawidłowa kwota" -#: ../../../src/ui.cpp:1928 -#: ../../../src/ui.cpp:1933 -#: ../../../src/ui.cpp:1938 -#: ../../../src/ui.cpp:1973 -#: ../../../src/uibase.cpp:55 +#: ../../../src/ui.cpp:2143 +#: ../../../src/ui.cpp:2148 +#: ../../../src/ui.cpp:2153 +#: ../../../src/ui.cpp:2202 +#: ../../../src/uibase.cpp:61 msgid "Send Coins" msgstr "Wyślij Monety" -#: ../../../src/ui.cpp:1933 +#: ../../../src/ui.cpp:2148 msgid "Amount exceeds your balance " msgstr "Kwota przekracza twój stan konta" -#: ../../../src/ui.cpp:1938 +#: ../../../src/ui.cpp:2153 msgid "Total exceeds your balance when the " msgstr "Przekroczenie twojego stanu konta gdy" -#: ../../../src/ui.cpp:1938 +#: ../../../src/ui.cpp:2153 msgid " transaction fee is included " msgstr " prowizja jest wliczona" -#: ../../../src/ui.cpp:1956 +#: ../../../src/ui.cpp:2176 msgid "Payment sent " msgstr "Wysłano płatność" -#: ../../../src/ui.cpp:1956 -#: ../../../src/ui.cpp:1961 -#: ../../../src/ui.cpp:2107 -#: ../../../src/ui.cpp:2260 -#: ../../../src/wallet.cpp:924 +#: ../../../src/ui.cpp:2176 +#: ../../../src/ui.cpp:2185 +#: ../../../src/ui.cpp:2336 +#: ../../../src/ui.cpp:2500 +#: ../../../src/wallet.cpp:1097 msgid "Sending..." msgstr "Wysyłanie..." -#: ../../../src/ui.cpp:1973 +#: ../../../src/ui.cpp:2202 msgid "Invalid address " msgstr "Nieprawidłowy adres" -#: ../../../src/ui.cpp:2028 +#: ../../../src/ui.cpp:2257 #, c-format msgid "Sending %s to %s" msgstr "Wysyłanie %s do %s" -#: ../../../src/ui.cpp:2101 -#: ../../../src/ui.cpp:2134 +#: ../../../src/ui.cpp:2330 +#: ../../../src/ui.cpp:2363 msgid "CANCELLED" msgstr "ANULOWANO" -#: ../../../src/ui.cpp:2105 +#: ../../../src/ui.cpp:2334 msgid "Cancelled" msgstr "Anulowano" -#: ../../../src/ui.cpp:2107 +#: ../../../src/ui.cpp:2336 msgid "Transfer cancelled " msgstr "Transfer anulowano" -#: ../../../src/ui.cpp:2160 +#: ../../../src/ui.cpp:2389 msgid "Error: " msgstr "Błąd:" -#: ../../../src/ui.cpp:2174 -#: ../../../src/ui.cpp:2245 -#: ../../../src/wallet.cpp:943 +#: ../../../src/ui.cpp:2403 +#: ../../../src/ui.cpp:2474 +#: ../../../src/wallet.cpp:1116 msgid "Insufficient funds" msgstr "Niewystarczające fundusze" -#: ../../../src/ui.cpp:2179 +#: ../../../src/ui.cpp:2408 msgid "Connecting..." msgstr "Łączenie..." -#: ../../../src/ui.cpp:2184 +#: ../../../src/ui.cpp:2413 msgid "Unable to connect" msgstr "Nie można połączyć" -#: ../../../src/ui.cpp:2189 +#: ../../../src/ui.cpp:2418 msgid "Requesting public key..." msgstr "Żądanie klucza publicznego..." -#: ../../../src/ui.cpp:2201 +#: ../../../src/ui.cpp:2430 msgid "Received public key..." msgstr "Otrzymano klucz publiczny..." -#: ../../../src/ui.cpp:2215 +#: ../../../src/ui.cpp:2444 msgid "Recipient is not accepting transactions sent by IP address" msgstr "Adresat nie akceptuje transakcji wysyłanych przez adres IP" -#: ../../../src/ui.cpp:2217 +#: ../../../src/ui.cpp:2446 msgid "Transfer was not accepted" msgstr "Transfer nie został zaakceptowany" -#: ../../../src/ui.cpp:2226 +#: ../../../src/ui.cpp:2455 msgid "Invalid response received" msgstr "Otrzymano niepoprawną odpowiedź" -#: ../../../src/ui.cpp:2241 +#: ../../../src/ui.cpp:2470 msgid "Creating transaction..." msgstr "Tworzenie transakcji..." -#: ../../../src/ui.cpp:2253 +#: ../../../src/ui.cpp:2489 #, c-format msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" msgstr "Ta transakcja wymaga prowizji co najmniej %s z uwagi na kwotę, złożoność lub użycie niedawno otrzymanych funduszy" -#: ../../../src/ui.cpp:2255 +#: ../../../src/ui.cpp:2491 msgid "Transaction creation failed" msgstr "Błąd tworzenia transakcji " -#: ../../../src/ui.cpp:2262 +#: ../../../src/ui.cpp:2502 msgid "Transaction aborted" msgstr "Transakcję przerwano" -#: ../../../src/ui.cpp:2270 +#: ../../../src/ui.cpp:2510 msgid "Lost connection, transaction cancelled" msgstr "Utracono połączenie, transakcja anulowana" -#: ../../../src/ui.cpp:2286 +#: ../../../src/ui.cpp:2526 msgid "Sending payment..." msgstr "Wysyłanie płatności..." -#: ../../../src/ui.cpp:2292 +#: ../../../src/ui.cpp:2532 msgid "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." msgstr "Transakcja została odrzucona. Może się tak zdarzyć jeżeli część monet w twoim portfelu zostało wydanych, np. gdy użyto kopii pliku wallet.dat i monety zostały wydane w kopii, a tutaj nie zostały oznaczone jako wydane." -#: ../../../src/ui.cpp:2301 +#: ../../../src/ui.cpp:2541 msgid "Waiting for confirmation..." msgstr "Oczekiwanie na potwierdzenie..." -#: ../../../src/ui.cpp:2319 +#: ../../../src/ui.cpp:2559 msgid "" "The payment was sent, but the recipient was unable to verify it.\n" "The transaction is recorded and will credit to the recipient,\n" @@ -603,84 +697,84 @@ "Transakcja została zarejestrowana i zostanie przypisana do odbiorcy,\n" "ale informacja w komentarzu będzie pusta." -#: ../../../src/ui.cpp:2328 +#: ../../../src/ui.cpp:2568 msgid "Payment was sent, but an invalid response was received" msgstr "Płatność została wysłana, ale otrzymano nieprawidłową odpowiedź" -#: ../../../src/ui.cpp:2334 +#: ../../../src/ui.cpp:2574 msgid "Payment completed" msgstr "Płatność zakończona" -#: ../../../src/ui.cpp:2376 -#: ../../../src/ui.cpp:2522 -#: ../../../src/ui.cpp:2559 +#: ../../../src/ui.cpp:2616 +#: ../../../src/ui.cpp:2764 +#: ../../../src/ui.cpp:2804 msgid "Name" msgstr "Nazwa" -#: ../../../src/ui.cpp:2377 -#: ../../../src/ui.cpp:2522 -#: ../../../src/ui.cpp:2559 +#: ../../../src/ui.cpp:2617 +#: ../../../src/ui.cpp:2764 +#: ../../../src/ui.cpp:2804 msgid "Address" msgstr "Adres" -#: ../../../src/ui.cpp:2379 -#: ../../../src/ui.cpp:2534 +#: ../../../src/ui.cpp:2619 +#: ../../../src/ui.cpp:2776 msgid "Label" msgstr "Etykieta" -#: ../../../src/ui.cpp:2380 -#: ../../../src/uibase.cpp:837 +#: ../../../src/ui.cpp:2620 +#: ../../../src/uibase.cpp:847 msgid "Bitcoin Address" msgstr "Adres Bitcoin" -#: ../../../src/ui.cpp:2504 +#: ../../../src/ui.cpp:2746 msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " msgstr "To jest jeden z twoich adresów na otrzymywane płatności i nie może zostać wpisany do księgi adresowej." -#: ../../../src/ui.cpp:2522 -#: ../../../src/ui.cpp:2528 +#: ../../../src/ui.cpp:2764 +#: ../../../src/ui.cpp:2770 msgid "Edit Address" msgstr "Edytuj Adres" -#: ../../../src/ui.cpp:2534 +#: ../../../src/ui.cpp:2776 msgid "Edit Address Label" msgstr "Edytuj Etykietę Adresu" -#: ../../../src/ui.cpp:2559 -#: ../../../src/ui.cpp:2565 +#: ../../../src/ui.cpp:2804 +#: ../../../src/ui.cpp:2810 msgid "Add Address" msgstr "Dodaj Adres" -#: ../../../src/ui.cpp:2642 +#: ../../../src/ui.cpp:2898 msgid "Bitcoin" msgstr "Bitcoin" -#: ../../../src/ui.cpp:2644 +#: ../../../src/ui.cpp:2900 msgid "Bitcoin - Generating" msgstr "Bitcoin - Generowanie" -#: ../../../src/ui.cpp:2646 +#: ../../../src/ui.cpp:2902 msgid "Bitcoin - (not connected)" msgstr "Bitcoin - (nie połączony)" -#: ../../../src/ui.cpp:2725 +#: ../../../src/ui.cpp:2981 msgid "&Open Bitcoin" msgstr "&Otwórz Bitcoin" -#: ../../../src/ui.cpp:2726 +#: ../../../src/ui.cpp:2982 msgid "&Send Bitcoins" msgstr "&Wyślij Bitcoiny" -#: ../../../src/ui.cpp:2727 +#: ../../../src/ui.cpp:2983 msgid "O&ptions..." msgstr "O&pcje..." -#: ../../../src/ui.cpp:2730 +#: ../../../src/ui.cpp:2986 #: ../../../src/uibase.cpp:25 msgid "E&xit" msgstr "W&yjście" -#: ../../../src/ui.cpp:2956 +#: ../../../src/ui.cpp:3212 msgid "Program has crashed and will terminate. " msgstr "Program uległ awarii i zostanie przerwany." @@ -696,152 +790,160 @@ msgid "&Your Receiving Addresses..." msgstr "&Twój Adres Odbiorczy..." -#: ../../../src/uibase.cpp:36 +#: ../../../src/uibase.cpp:35 +msgid "&Encrypt Wallet..." +msgstr "&Zaszyfruj portfel..." + +#: ../../../src/uibase.cpp:38 +msgid "&Change Wallet Encryption Passphrase..." +msgstr "&Zmień hasło szyfrowania portfela..." + +#: ../../../src/uibase.cpp:42 msgid "&Options..." msgstr "&Opcje..." -#: ../../../src/uibase.cpp:39 +#: ../../../src/uibase.cpp:45 msgid "&Settings" msgstr "&Ustawienia" -#: ../../../src/uibase.cpp:43 +#: ../../../src/uibase.cpp:49 msgid "&About..." msgstr "&O programie..." -#: ../../../src/uibase.cpp:46 +#: ../../../src/uibase.cpp:52 msgid "&Help" msgstr "&Pomoc" -#: ../../../src/uibase.cpp:56 +#: ../../../src/uibase.cpp:62 msgid "Address Book" msgstr "Księga Adresowa" -#: ../../../src/uibase.cpp:69 +#: ../../../src/uibase.cpp:75 msgid "Your Bitcoin Address:" msgstr "Twój Adres Bitcoin:" -#: ../../../src/uibase.cpp:76 +#: ../../../src/uibase.cpp:82 msgid " &New... " msgstr " &Nowy..." -#: ../../../src/uibase.cpp:79 -#: ../../../src/uibase.cpp:780 -#: ../../../src/uibase.cpp:883 +#: ../../../src/uibase.cpp:85 +#: ../../../src/uibase.cpp:790 +#: ../../../src/uibase.cpp:893 msgid " &Copy to Clipboard " msgstr " &Kopiuj do schowka " -#: ../../../src/uibase.cpp:93 +#: ../../../src/uibase.cpp:99 msgid "Balance:" msgstr "Saldo:" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " All" msgstr " Wszystko" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Sent" msgstr "Wysłano" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Received" msgstr "Otrzymano" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " In Progress" msgstr "W Trakcie" -#: ../../../src/uibase.cpp:130 +#: ../../../src/uibase.cpp:136 msgid "All Transactions" msgstr "Wszystkie Transakcje" -#: ../../../src/uibase.cpp:141 +#: ../../../src/uibase.cpp:147 msgid "Sent/Received" msgstr "Wysłano/Otrzymano" -#: ../../../src/uibase.cpp:152 +#: ../../../src/uibase.cpp:158 msgid "Sent" msgstr "Wysłano" -#: ../../../src/uibase.cpp:163 +#: ../../../src/uibase.cpp:169 msgid "Received" msgstr "Otrzymano" -#: ../../../src/uibase.cpp:302 -#: ../../../src/uibase.cpp:443 -#: ../../../src/uibase.cpp:542 -#: ../../../src/uibase.cpp:722 -#: ../../../src/uibase.cpp:783 -#: ../../../src/uibase.cpp:892 -#: ../../../src/uibase.cpp:981 +#: ../../../src/uibase.cpp:312 +#: ../../../src/uibase.cpp:453 +#: ../../../src/uibase.cpp:552 +#: ../../../src/uibase.cpp:732 +#: ../../../src/uibase.cpp:793 +#: ../../../src/uibase.cpp:902 +#: ../../../src/uibase.cpp:991 msgid "OK" msgstr "OK" -#: ../../../src/uibase.cpp:345 +#: ../../../src/uibase.cpp:355 msgid "&Start Bitcoin on system startup" msgstr "&Uruchom Bitcoin wraz ze startem systemu" -#: ../../../src/uibase.cpp:348 +#: ../../../src/uibase.cpp:358 msgid "&Minimize to the tray instead of the taskbar" msgstr "&Zminimalizuj do traya zamiast do paska zadań" -#: ../../../src/uibase.cpp:351 +#: ../../../src/uibase.cpp:361 msgid "Map port using &UPnP" msgstr "Mapuj port używając &UPnP" -#: ../../../src/uibase.cpp:354 +#: ../../../src/uibase.cpp:364 msgid "M&inimize to the tray on close" msgstr "Zm&inimalizuj do traya przy zamknięciu" -#: ../../../src/uibase.cpp:360 +#: ../../../src/uibase.cpp:370 msgid "&Connect through socks4 proxy: " msgstr "&Połącz przez socks4 proxy:" -#: ../../../src/uibase.cpp:371 +#: ../../../src/uibase.cpp:381 msgid "Proxy &IP:" msgstr "Proxy &IP:" -#: ../../../src/uibase.cpp:379 +#: ../../../src/uibase.cpp:389 msgid " &Port:" msgstr " &Port:" -#: ../../../src/uibase.cpp:392 +#: ../../../src/uibase.cpp:402 msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." msgstr "Opcjonalna prowizja określona dla KB transakcji, która zapewni, że twoje transakcje będą szybko przetworzone. Większość transakcji to 1KB. Rekomendowana prowizja to 0.01." -#: ../../../src/uibase.cpp:399 +#: ../../../src/uibase.cpp:409 msgid "Pay transaction fee:" msgstr "Płać prowizję transakcji:" -#: ../../../src/uibase.cpp:420 +#: ../../../src/uibase.cpp:430 msgid "// [don't translate] Test panel 2 for future expansion" msgstr "" -#: ../../../src/uibase.cpp:424 +#: ../../../src/uibase.cpp:434 msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" msgstr "" -#: ../../../src/uibase.cpp:446 -#: ../../../src/uibase.cpp:668 -#: ../../../src/uibase.cpp:727 -#: ../../../src/uibase.cpp:786 -#: ../../../src/uibase.cpp:895 -#: ../../../src/uibase.cpp:984 +#: ../../../src/uibase.cpp:456 +#: ../../../src/uibase.cpp:678 +#: ../../../src/uibase.cpp:737 +#: ../../../src/uibase.cpp:796 +#: ../../../src/uibase.cpp:905 +#: ../../../src/uibase.cpp:994 msgid "Cancel" msgstr "Anuluj" -#: ../../../src/uibase.cpp:449 +#: ../../../src/uibase.cpp:459 msgid "&Apply" msgstr "&Zastosuj" -#: ../../../src/uibase.cpp:508 +#: ../../../src/uibase.cpp:518 msgid "Bitcoin " msgstr "Bitcoin" -#: ../../../src/uibase.cpp:514 +#: ../../../src/uibase.cpp:524 msgid "version" msgstr "wersja" -#: ../../../src/uibase.cpp:525 +#: ../../../src/uibase.cpp:535 msgid "" "Copyright (c) 2009-2011 Bitcoin Developers\n" "\n" @@ -865,39 +967,39 @@ "OpenSSL Toolkit (http://www.openssl.org/) i oprogramowanie kryptograficzne napisane przez \n" "Erica Younga (eay@cryptsoft.com) oraz oprogramowanie UPnP napisane przez Thomasa Bernarda." -#: ../../../src/uibase.cpp:581 +#: ../../../src/uibase.cpp:591 msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" msgstr "Wprowadź adres Bitcoin (np. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" -#: ../../../src/uibase.cpp:595 +#: ../../../src/uibase.cpp:605 msgid "Pay &To:" msgstr "Wpłać &Dla:" -#: ../../../src/uibase.cpp:610 +#: ../../../src/uibase.cpp:620 msgid "&Paste" msgstr "&Wklej" -#: ../../../src/uibase.cpp:613 +#: ../../../src/uibase.cpp:623 msgid " Address &Book..." msgstr " Księga &Adresowa..." -#: ../../../src/uibase.cpp:620 +#: ../../../src/uibase.cpp:630 msgid "&Amount:" msgstr "&Kwota:" -#: ../../../src/uibase.cpp:630 +#: ../../../src/uibase.cpp:640 msgid "T&ransfer:" msgstr "T&ransfer:" -#: ../../../src/uibase.cpp:636 +#: ../../../src/uibase.cpp:646 msgid " Standard" msgstr " Standard" -#: ../../../src/uibase.cpp:663 +#: ../../../src/uibase.cpp:673 msgid "&Send" msgstr "&Wyślij" -#: ../../../src/uibase.cpp:711 +#: ../../../src/uibase.cpp:721 msgid "" "\n" "\n" @@ -907,70 +1009,74 @@ "\n" "Łączenie..." -#: ../../../src/uibase.cpp:761 +#: ../../../src/uibase.cpp:771 msgid "These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window." msgstr "To są twoje adresy Bitcoin dla otrzymywania płatności. Możesz chcieć podać różne dla każdego płacącego aby kontrolować kto ci płaci. Wyróżniony adres będzie wyświetlany w oknie głównym." -#: ../../../src/uibase.cpp:774 -#: ../../../src/uibase.cpp:886 +#: ../../../src/uibase.cpp:784 +#: ../../../src/uibase.cpp:896 msgid "&Edit..." msgstr "&Edytuj..." -#: ../../../src/uibase.cpp:777 -#: ../../../src/uibase.cpp:889 +#: ../../../src/uibase.cpp:787 +#: ../../../src/uibase.cpp:899 msgid " &New Address... " msgstr " &Nowy Adres..." -#: ../../../src/uibase.cpp:849 +#: ../../../src/uibase.cpp:859 msgid "Sending" msgstr "Wysyłanie" -#: ../../../src/uibase.cpp:857 +#: ../../../src/uibase.cpp:867 msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." msgstr "To są twoje adresy Bitcoin dla otrzymywania płatności. Możesz podać różne dla każdego płacącego aby kontrolować kto ci płaci. Wyróżniony adres będzie wyświetlany w oknie głównym." -#: ../../../src/uibase.cpp:870 +#: ../../../src/uibase.cpp:880 msgid "Receiving" msgstr "Otrzymywanie" -#: ../../../src/uibase.cpp:880 +#: ../../../src/uibase.cpp:890 msgid "&Delete" msgstr "&Usuń" -#: ../../../src/wallet.cpp:917 +#: ../../../src/wallet.cpp:1081 +msgid "Error: Wallet locked, unable to create transaction " +msgstr "Błąd: Portfel zablokowany, nie można utworzyć transakcji" + +#: ../../../src/wallet.cpp:1089 #, c-format msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " msgstr "Błąd: Ta transakcja wymaga prowizji co najmniej %s z uwagi na kwotę, złożoność lub użycie niedawno otrzymanych funduszy" -#: ../../../src/wallet.cpp:919 +#: ../../../src/wallet.cpp:1091 msgid "Error: Transaction creation failed " msgstr "Błąd: Nie udało się utworzyć transakcji" -#: ../../../src/wallet.cpp:928 +#: ../../../src/wallet.cpp:1101 msgid "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." msgstr "Błąd: Transakcja została odrzucona. Może się tak zdarzyć jeżeli część monet w twoim portfelu zostało wydanych, np. gdy użyto kopii pliku wallet.dat i monety zostały wydane w kopii, a tutaj nie zostały oznaczone jako wydane." -#: ../../../src/wallet.cpp:941 +#: ../../../src/wallet.cpp:1114 msgid "Invalid amount" msgstr "Niewłaściwa kwota" -#: ../../../src/wallet.cpp:948 +#: ../../../src/wallet.cpp:1121 msgid "Invalid bitcoin address" msgstr "Niewłaściwy adres bitcoin" -#: ../../../src/uibase.h:147 +#: ../../../src/uibase.h:151 msgid "Transaction Details" msgstr "Szczegóły Transakcji" -#: ../../../src/uibase.h:199 +#: ../../../src/uibase.h:203 msgid "Options" msgstr "Opcje" -#: ../../../src/uibase.h:228 +#: ../../../src/uibase.h:232 msgid "About Bitcoin" msgstr "O Bitcoin" -#: ../../../src/uibase.h:337 +#: ../../../src/uibase.h:341 msgid "Your Bitcoin Addresses" msgstr "Twoje Adresy Bitcoin"
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b61914cb4b3824e907dfa2c58acfe16a8af0467d GIT binary patch literal 20407 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 B!94%~
--- a/locale/sv/LC_MESSAGES/bitcoin.po +++ b/locale/sv/LC_MESSAGES/bitcoin.po @@ -2,8 +2,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-06-11 21:58+0100\n" -"PO-Revision-Date: 2011-06-14 09:01+0100\n" +"POT-Creation-Date: 2011-07-03 10:40+0100\n" +"PO-Revision-Date: 2011-07-03 15:13+0100\n" "Last-Translator: Codler <github>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -11,130 +11,133 @@ "Content-Transfer-Encoding: 8bit\n" "X-Poedit-KeywordsList: _;gettext;gettext_noop\n" "X-Poedit-Basepath: .\n" -"X-Poedit-Bookmarks: 35,145,-1,-1,-1,-1,-1,-1,-1,-1\n" "X-Poedit-SearchPath-0: ../../..\n" -#: ../../../init.cpp:141 +#: ../../../init.cpp:162 msgid "Bitcoin version" msgstr "Bitcoin version" -#: ../../../init.cpp:142 +#: ../../../init.cpp:163 msgid "Usage:" msgstr "Användning:" -#: ../../../init.cpp:144 +#: ../../../init.cpp:165 msgid "Send command to -server or bitcoind\n" msgstr "Skicka kommando till -server eller bitcoind\n" -#: ../../../init.cpp:145 +#: ../../../init.cpp:166 msgid "List commands\n" msgstr "Lista kommandon\n" -#: ../../../init.cpp:146 +#: ../../../init.cpp:167 msgid "Get help for a command\n" msgstr "Få hjälp om kommandon\n" -#: ../../../init.cpp:147 +#: ../../../init.cpp:168 msgid "Options:\n" msgstr "Val:\n" -#: ../../../init.cpp:148 +#: ../../../init.cpp:169 msgid "Specify configuration file (default: bitcoin.conf)\n" msgstr "Ange konfigurationsfil (standard: bitcoin.conf)\n" -#: ../../../init.cpp:149 +#: ../../../init.cpp:170 msgid "Specify pid file (default: bitcoind.pid)\n" msgstr "Ange pid-fil (standard: bitcoind.pid)\n" -#: ../../../init.cpp:150 +#: ../../../init.cpp:171 msgid "Generate coins\n" msgstr "Generera mynt\n" -#: ../../../init.cpp:151 +#: ../../../init.cpp:172 msgid "Don't generate coins\n" msgstr "Generera inte mynt\n" -#: ../../../init.cpp:152 +#: ../../../init.cpp:173 msgid "Start minimized\n" msgstr "Starta minimerad\n" -#: ../../../init.cpp:153 +#: ../../../init.cpp:174 msgid "Specify data directory\n" msgstr "Ange data mappen\n" -#: ../../../init.cpp:154 +#: ../../../init.cpp:175 +msgid "Specify connection timeout (in milliseconds)\n" +msgstr "Ange timeout för anslutning (i millisekunder)\n" + +#: ../../../init.cpp:176 msgid "Connect through socks4 proxy\n" msgstr "Anslut via socks4 proxy\n" -#: ../../../init.cpp:155 +#: ../../../init.cpp:177 msgid "Allow DNS lookups for addnode and connect\n" msgstr "Tillåt DNS uppslagningar för addnode och connect\n" -#: ../../../init.cpp:156 +#: ../../../init.cpp:178 msgid "Add a node to connect to\n" msgstr "Lägg till en nod att ansluta till\n" -#: ../../../init.cpp:157 +#: ../../../init.cpp:179 msgid "Connect only to the specified node\n" msgstr "Anslut endast till specifik nod\n" -#: ../../../init.cpp:158 +#: ../../../init.cpp:180 msgid "Don't accept connections from outside\n" msgstr "Acceptera ej anslutningar från utsidan\n" -#: ../../../init.cpp:161 +#: ../../../init.cpp:183 msgid "Don't attempt to use UPnP to map the listening port\n" msgstr "Försöker inte använda UPnP till avslyssningsport\n" -#: ../../../init.cpp:163 +#: ../../../init.cpp:185 msgid "Attempt to use UPnP to map the listening port\n" msgstr "Försöker använda UPnP till avlyssningsport\n" -#: ../../../init.cpp:166 +#: ../../../init.cpp:188 msgid "Fee per KB to add to transactions you send\n" msgstr "Avgift per KB som läggs på transaktionen när du sänder\n" -#: ../../../init.cpp:168 +#: ../../../init.cpp:190 msgid "Accept command line and JSON-RPC commands\n" msgstr "Accepterar kommandorad och JSON-RPC kommando\n" -#: ../../../init.cpp:171 +#: ../../../init.cpp:193 msgid "Run in the background as a daemon and accept commands\n" msgstr "Kör i bakgrund som daemon och accepterar kommando\n" -#: ../../../init.cpp:173 +#: ../../../init.cpp:195 msgid "Use the test network\n" msgstr "Använd test nätverk\n" -#: ../../../init.cpp:174 +#: ../../../init.cpp:196 msgid "Username for JSON-RPC connections\n" msgstr "Användarnamn till JSON-RPC anslutning\n" -#: ../../../init.cpp:175 +#: ../../../init.cpp:197 msgid "Password for JSON-RPC connections\n" msgstr "Lösenord till JSON-RPC anslutning\n" -#: ../../../init.cpp:176 +#: ../../../init.cpp:198 msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" msgstr "Lyssnar på JSON-RPC anslutningar på <port> (standard: 8332)\n" -#: ../../../init.cpp:177 +#: ../../../init.cpp:199 msgid "Allow JSON-RPC connections from specified IP address\n" msgstr "Tillåt JSON-RPC anslutningar från specifik IP-adress\n" -#: ../../../init.cpp:178 +#: ../../../init.cpp:200 msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" msgstr "Skicka kommando till noden som körs på <ip> (standard: 127.0.0.1)\n" -#: ../../../init.cpp:179 +#: ../../../init.cpp:201 msgid "Set key pool size to <n> (default: 100)\n" msgstr "Sätt nyckel pool storlek till <n> (standard: 100)\n" -#: ../../../init.cpp:180 +#: ../../../init.cpp:202 msgid "Rescan the block chain for missing wallet transactions\n" msgstr "Scanna om block kedja efter saknade plånbokstransaktioner\n" -#: ../../../init.cpp:184 +#: ../../../init.cpp:206 msgid "" "\n" "SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" @@ -142,106 +145,71 @@ "\n" "SSL val: (Se på Bitcoin Wiki för SSL installation instruktioner)\n" -#: ../../../init.cpp:185 +#: ../../../init.cpp:207 msgid "Use OpenSSL (https) for JSON-RPC connections\n" msgstr "Använd OpenSSL (https) till JSON-RPC anslutningar\n" -#: ../../../init.cpp:186 +#: ../../../init.cpp:208 msgid "Server certificate file (default: server.cert)\n" msgstr "Server certifikatfil (standard: server.cert)\n" -#: ../../../init.cpp:187 +#: ../../../init.cpp:209 msgid "Server private key (default: server.pem)\n" msgstr "Server privat nyckel (standard: server.pem)\n" -#: ../../../init.cpp:188 +#: ../../../init.cpp:210 msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" msgstr "Acceptabla krypteringar (standard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" -#: ../../../init.cpp:192 +#: ../../../init.cpp:214 msgid "This help message\n" msgstr "Detta hjälpmeddelande\n" -#: ../../../init.cpp:329 +#: ../../../init.cpp:351 #, c-format msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." msgstr "Kan inte sätta lås på data mappen %s. Bitcoin körs troligen redan." -#: ../../../init.cpp:355 +#: ../../../init.cpp:377 msgid "Error loading addr.dat \n" msgstr "Fel vid laddning av addr.dat \n" -#: ../../../init.cpp:361 +#: ../../../init.cpp:383 msgid "Error loading blkindex.dat \n" msgstr "Fel vid laddning av blkindex.dat \n" -#: ../../../init.cpp:368 +#: ../../../init.cpp:391 msgid "Error loading wallet.dat \n" msgstr "Fel vid laddning av wallet.dat \n" -#: ../../../init.cpp:448 +#: ../../../init.cpp:481 msgid "Invalid -proxy address" msgstr "Ogiltig -proxy adress" -#: ../../../init.cpp:471 +#: ../../../init.cpp:506 msgid "Invalid amount for -paytxfee=<amount>" msgstr "Ogiltig belopp på -paytxfee=<belopp>" -#: ../../../init.cpp:475 +#: ../../../init.cpp:510 msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." msgstr "Varning: -paytxfee är satt väldigt högt. Denna är transaktionsavgiften som du kommer att betala om du skickar en transaktion." -#: ../../../main.cpp:1866 +#: ../../../main.cpp:1430 msgid "Warning: Disk space is low " msgstr "Varning: Diskutrymme är låg " -#: ../../../main.cpp:3999 -#, c-format -msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " -msgstr "Fel: Denna transaktion kräver en transaktionsavgift minst %s för dess belopp, komplexitet, eller användning av nyligen mottagna pengar " - -#: ../../../main.cpp:4001 -msgid "Error: Transaction creation failed " -msgstr "Fel: Misslyckades att skapa transaktion " - -#: ../../../main.cpp:4006 -#: ../../../ui.cpp:1951 -#: ../../../ui.cpp:1956 -#: ../../../ui.cpp:2102 -#: ../../../ui.cpp:2255 -msgid "Sending..." -msgstr "Skickar..." - -#: ../../../main.cpp:4010 -msgid "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." -msgstr "Fel: Transaktionen blev nekad. Detta kan hända om några av dina mynt i din plånbok var redan spenderad. Till exempel om du använde en kopia av wallet.dat och mynten var redan spenderad i kopian, men som inte var markerad som spenderad här." - -#: ../../../main.cpp:4023 -msgid "Invalid amount" -msgstr "Ogiltig belopp" - -#: ../../../main.cpp:4025 -#: ../../../ui.cpp:2169 -#: ../../../ui.cpp:2240 -msgid "Insufficient funds" -msgstr "Otillräckligt med pengar" - -#: ../../../main.cpp:4030 -msgid "Invalid bitcoin address" -msgstr "Ogiltig bitcoin adress" - -#: ../../../net.cpp:1505 +#: ../../../net.cpp:1598 #, c-format msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." msgstr "Det gick inte att binda till port %d på denna dator. Bitcoin körs troligen redan." -#: ../../../rpc.cpp:1816 -#: ../../../rpc.cpp:1818 +#: ../../../rpc.cpp:1828 +#: ../../../rpc.cpp:1830 #, c-format msgid "To use the %s option" msgstr "För att använda %s val" -#: ../../../rpc.cpp:1820 +#: ../../../rpc.cpp:1832 #, c-format msgid "" "Warning: %s, you must set rpcpassword=<password>\n" @@ -252,7 +220,7 @@ "i konfigurationsfilen: %s\n" "Om filen inte existerar, skapa med ägare med filbehörigheten -readable-only.\n" -#: ../../../rpc.cpp:1988 +#: ../../../rpc.cpp:2005 #, c-format msgid "" "You must set rpcpassword=<password> in the configuration file:\n" @@ -263,347 +231,360 @@ "%s\n" "Om filen inte existerar, skapa med ägare med filbehörighete -readable-only." -#: ../../../ui.cpp:211 +#: ../../../ui.cpp:216 #, c-format msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" msgstr "Denna transaktion är över storleksbegränsningen. Du kan fortfarande skicka mot en avgift på %s, som går till noderna som bearbetar din transaktion och hjälper att stödja nätverket. Vill du fortfarande betala avgiften?" -#: ../../../ui.cpp:311 +#: ../../../ui.cpp:316 msgid "Status" msgstr "Status" -#: ../../../ui.cpp:312 +#: ../../../ui.cpp:317 msgid "Date" msgstr "Datum" -#: ../../../ui.cpp:313 +#: ../../../ui.cpp:318 msgid "Description" msgstr "Beskrivning" -#: ../../../ui.cpp:314 +#: ../../../ui.cpp:319 msgid "Debit" -msgstr "Debitera" +msgstr "Debet" -#: ../../../ui.cpp:315 +#: ../../../ui.cpp:320 msgid "Credit" -msgstr "Kreditera" +msgstr "Kredit" -#: ../../../ui.cpp:521 +#: ../../../ui.cpp:526 #, c-format msgid "Open for %d blocks" -msgstr "Öppna för %d blocks" +msgstr "Öppen för %d block" -#: ../../../ui.cpp:523 +#: ../../../ui.cpp:528 #, c-format msgid "Open until %s" msgstr "Öppen tills %s" -#: ../../../ui.cpp:529 +#: ../../../ui.cpp:534 #, c-format msgid "%d/offline?" msgstr "%d/offline?" -#: ../../../ui.cpp:531 +#: ../../../ui.cpp:536 #, c-format msgid "%d/unconfirmed" msgstr "%d/obekräftade" -#: ../../../ui.cpp:533 +#: ../../../ui.cpp:538 #, c-format msgid "%d confirmations" msgstr "%d bekräftelser" -#: ../../../ui.cpp:618 +#: ../../../ui.cpp:623 msgid "Generated" msgstr "Genererad" -#: ../../../ui.cpp:626 -#, fuzzy, c-format +#: ../../../ui.cpp:631 +#, c-format msgid "Generated (%s matures in %d more blocks)" -msgstr "Genererad (%s mogna i %d fler block)" +msgstr "Genererad (%s mognar om %d block)" -#: ../../../ui.cpp:630 +#: ../../../ui.cpp:635 msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" msgstr "Genererad - Varning: Denna block har inte blivit mottagen av någon annan nod och kommer troligtvis inte bli accepterad" -#: ../../../ui.cpp:634 +#: ../../../ui.cpp:639 msgid "Generated (not accepted)" msgstr "Genererad (ej accepterad)" -#: ../../../ui.cpp:644 +#: ../../../ui.cpp:649 msgid "From: " msgstr "Från: " -#: ../../../ui.cpp:668 +#: ../../../ui.cpp:673 msgid "Received with: " msgstr "Mottagen med: " -#: ../../../ui.cpp:714 +#: ../../../ui.cpp:719 msgid "Payment to yourself" msgstr "Betalning till dig själv" -#: ../../../ui.cpp:748 +#: ../../../ui.cpp:753 msgid "To: " msgstr "Till: " -#: ../../../ui.cpp:1063 +#: ../../../ui.cpp:1068 msgid " Generating" msgstr " Generering" -#: ../../../ui.cpp:1065 +#: ../../../ui.cpp:1070 msgid "(not connected)" msgstr "(inte ansluten)" -#: ../../../ui.cpp:1068 +#: ../../../ui.cpp:1073 #, c-format msgid " %d connections %d blocks %d transactions" msgstr " %d anslutningar %d block %d transaktioner" -#: ../../../ui.cpp:1173 -#: ../../../ui.cpp:2566 +#: ../../../ui.cpp:1178 +#: ../../../ui.cpp:2577 msgid "New Receiving Address" msgstr "Ny Mottagningsadress" -#: ../../../ui.cpp:1174 -#: ../../../ui.cpp:2567 +#: ../../../ui.cpp:1179 +#: ../../../ui.cpp:2578 msgid "" "You should use a new address for each payment you receive.\n" "\n" "Label" msgstr "" -"Du borde använda en ny adress för varje betalning som du mottar.\n" +"Du borde använda en ny adress för varje betalning som du mottagit.\n" "\n" "Etikett" -#: ../../../ui.cpp:1246 +#: ../../../ui.cpp:1252 msgid "<b>Status:</b> " msgstr "<b>Status:</b> " -#: ../../../ui.cpp:1251 +#: ../../../ui.cpp:1257 msgid ", has not been successfully broadcast yet" -msgstr ", has not been successfully broadcast yet" +msgstr ", har inte lyckats broadcast än" -#: ../../../ui.cpp:1253 +#: ../../../ui.cpp:1259 #, c-format msgid ", broadcast through %d node" msgstr ", broadcast genom %d nod" -#: ../../../ui.cpp:1255 +#: ../../../ui.cpp:1261 #, c-format msgid ", broadcast through %d nodes" msgstr ", broadcast genom %d noder" -#: ../../../ui.cpp:1259 +#: ../../../ui.cpp:1265 msgid "<b>Date:</b> " msgstr "<b>Datum:</b> " -#: ../../../ui.cpp:1267 +#: ../../../ui.cpp:1273 msgid "<b>Source:</b> Generated<br>" msgstr "<b>Källa:</b> Genererad<br>" -#: ../../../ui.cpp:1273 -#: ../../../ui.cpp:1291 +#: ../../../ui.cpp:1279 +#: ../../../ui.cpp:1297 msgid "<b>From:</b> " msgstr "<b>Från:</b> " -#: ../../../ui.cpp:1291 +#: ../../../ui.cpp:1297 msgid "unknown" msgstr "okänd" -#: ../../../ui.cpp:1292 -#: ../../../ui.cpp:1316 -#: ../../../ui.cpp:1375 +#: ../../../ui.cpp:1298 +#: ../../../ui.cpp:1322 +#: ../../../ui.cpp:1381 msgid "<b>To:</b> " msgstr "<b>Till:</b> " -#: ../../../ui.cpp:1295 +#: ../../../ui.cpp:1301 msgid " (yours, label: " msgstr " (din, etikett: " -#: ../../../ui.cpp:1297 +#: ../../../ui.cpp:1303 msgid " (yours)" msgstr " (ditt)" -#: ../../../ui.cpp:1334 -#: ../../../ui.cpp:1346 -#: ../../../ui.cpp:1392 -#: ../../../ui.cpp:1409 +#: ../../../ui.cpp:1340 +#: ../../../ui.cpp:1352 +#: ../../../ui.cpp:1398 +#: ../../../ui.cpp:1415 msgid "<b>Credit:</b> " msgstr "<b>Kredit:</b> " -#: ../../../ui.cpp:1336 -#, fuzzy, c-format +#: ../../../ui.cpp:1342 +#, c-format msgid "(%s matures in %d more blocks)" -msgstr "(%s matures in %d more blocks)" +msgstr "(%s mognar om %d block)" -#: ../../../ui.cpp:1338 +#: ../../../ui.cpp:1344 msgid "(not accepted)" msgstr "(ej accepterad)" -#: ../../../ui.cpp:1383 -#: ../../../ui.cpp:1391 -#: ../../../ui.cpp:1406 +#: ../../../ui.cpp:1389 +#: ../../../ui.cpp:1397 +#: ../../../ui.cpp:1412 msgid "<b>Debit:</b> " -msgstr "<b>Debit:</b> " +msgstr "<b>Debet:</b> " -#: ../../../ui.cpp:1397 +#: ../../../ui.cpp:1403 msgid "<b>Transaction fee:</b> " msgstr "<b>Transaktionsavgift:</b> " -#: ../../../ui.cpp:1413 -#, fuzzy +#: ../../../ui.cpp:1419 msgid "<b>Net amount:</b> " msgstr "<b>Nät belopp:</b> " -#: ../../../ui.cpp:1420 +#: ../../../ui.cpp:1426 msgid "Message:" msgstr "Meddelande:" -#: ../../../ui.cpp:1422 +#: ../../../ui.cpp:1428 msgid "Comment:" msgstr "Kommentar:" -#: ../../../ui.cpp:1425 +#: ../../../ui.cpp:1431 msgid "Generated coins must wait 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." msgstr "Genererad mynt måste vänta 120 block innan dem kan användas.När du genererat denna block, skickades en broadcast till nätet och lades till block kedjan. Om den misslyckas att lägga till kedjan så kommer det ändras till \"not accepted\" och är icke brukbar. Detta kan hända om en annan nod genererat en block några sekunder efter din." -#: ../../../ui.cpp:1605 +#: ../../../ui.cpp:1611 msgid "Cannot write autostart/bitcoin.desktop file" msgstr "Kan inte skriva autostart/bitcoin.desktop fil" -#: ../../../ui.cpp:1641 +#: ../../../ui.cpp:1647 msgid "Main" -msgstr "Huvud" +msgstr "Allmänt" -#: ../../../ui.cpp:1651 +#: ../../../ui.cpp:1657 msgid "&Start Bitcoin on window system startup" -msgstr "&Starta Bitcoin vid uppstart i windows" +msgstr "&Starta Bitcoin vid system uppstart" -#: ../../../ui.cpp:1658 +#: ../../../ui.cpp:1664 msgid "&Minimize on close" msgstr "&Minimera vid stängning" -#: ../../../ui.cpp:1800 +#: ../../../ui.cpp:1806 #, c-format msgid "version %s" msgstr "version %s" -#: ../../../ui.cpp:1923 +#: ../../../ui.cpp:1929 msgid "Error in amount " msgstr "Fel i belopp " -#: ../../../ui.cpp:1923 -#: ../../../ui.cpp:1928 -#: ../../../ui.cpp:1933 -#: ../../../ui.cpp:1968 +#: ../../../ui.cpp:1929 +#: ../../../ui.cpp:1934 +#: ../../../ui.cpp:1939 +#: ../../../ui.cpp:1974 #: ../../../uibase.cpp:55 msgid "Send Coins" msgstr "Skicka mynt" -#: ../../../ui.cpp:1928 +#: ../../../ui.cpp:1934 msgid "Amount exceeds your balance " msgstr "Belopp överskrider din balans " -#: ../../../ui.cpp:1933 +#: ../../../ui.cpp:1939 msgid "Total exceeds your balance when the " -msgstr "Totals överskrider din balans när " +msgstr "Totalt överskrider din balans när " -#: ../../../ui.cpp:1933 +#: ../../../ui.cpp:1939 msgid " transaction fee is included " msgstr " transaktionsavgift är inkluderad " -#: ../../../ui.cpp:1951 +#: ../../../ui.cpp:1957 msgid "Payment sent " msgstr "Betalning skickad " -#: ../../../ui.cpp:1968 +#: ../../../ui.cpp:1957 +#: ../../../ui.cpp:1962 +#: ../../../ui.cpp:2108 +#: ../../../ui.cpp:2261 +#: ../../../wallet.cpp:924 +msgid "Sending..." +msgstr "Skickar..." + +#: ../../../ui.cpp:1974 msgid "Invalid address " msgstr "Ogiltig adress " -#: ../../../ui.cpp:2023 +#: ../../../ui.cpp:2029 #, c-format msgid "Sending %s to %s" msgstr "Skickar %s till %s" -#: ../../../ui.cpp:2096 -#: ../../../ui.cpp:2129 +#: ../../../ui.cpp:2102 +#: ../../../ui.cpp:2135 msgid "CANCELLED" msgstr "AVBRUTEN" -#: ../../../ui.cpp:2100 +#: ../../../ui.cpp:2106 msgid "Cancelled" msgstr "Avbruten" -#: ../../../ui.cpp:2102 +#: ../../../ui.cpp:2108 msgid "Transfer cancelled " msgstr "Överföring avbruten " -#: ../../../ui.cpp:2155 +#: ../../../ui.cpp:2161 msgid "Error: " msgstr "Fel: " -#: ../../../ui.cpp:2174 +#: ../../../ui.cpp:2175 +#: ../../../ui.cpp:2246 +#: ../../../wallet.cpp:943 +msgid "Insufficient funds" +msgstr "Otillräckligt med pengar" + +#: ../../../ui.cpp:2180 msgid "Connecting..." msgstr "Ansluter..." -#: ../../../ui.cpp:2179 +#: ../../../ui.cpp:2185 msgid "Unable to connect" msgstr "Det gick inte att ansluta" -#: ../../../ui.cpp:2184 +#: ../../../ui.cpp:2190 msgid "Requesting public key..." msgstr "Efterfrågar publik nyckel..." -#: ../../../ui.cpp:2196 +#: ../../../ui.cpp:2202 msgid "Received public key..." msgstr "Mottagen publik nyckel..." -#: ../../../ui.cpp:2210 +#: ../../../ui.cpp:2216 msgid "Recipient is not accepting transactions sent by IP address" msgstr "Mottagaren accepterar inte transaktioner skickat från IP adress" -#: ../../../ui.cpp:2212 +#: ../../../ui.cpp:2218 msgid "Transfer was not accepted" msgstr "Överföringen var inte accepterad" -#: ../../../ui.cpp:2221 +#: ../../../ui.cpp:2227 msgid "Invalid response received" msgstr "Ogiltig respons mottagen" -#: ../../../ui.cpp:2236 +#: ../../../ui.cpp:2242 msgid "Creating transaction..." msgstr "Skapar transation..." -#: ../../../ui.cpp:2248 +#: ../../../ui.cpp:2254 #, c-format msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" msgstr "Denna transaktion kräver en transaktionsavgift minst %s för dess belopp, komplexitet, eller användning av nyligen mottagna pengar" -#: ../../../ui.cpp:2250 +#: ../../../ui.cpp:2256 msgid "Transaction creation failed" msgstr "Misslyckades skapa transaktion" -#: ../../../ui.cpp:2257 +#: ../../../ui.cpp:2263 msgid "Transaction aborted" msgstr "Transaktion avbruten" -#: ../../../ui.cpp:2265 +#: ../../../ui.cpp:2271 msgid "Lost connection, transaction cancelled" msgstr "Förlorad anslutning, transaktionen avbruten" -#: ../../../ui.cpp:2281 +#: ../../../ui.cpp:2287 msgid "Sending payment..." msgstr "Skickar betalning..." -#: ../../../ui.cpp:2287 +#: ../../../ui.cpp:2293 msgid "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." msgstr "Transaktionen blev nekad. Detta kan hända om några av dina mynt i din plånbok var redan spenderad. Till exempel om du använde en kopia av wallet.dat och mynten var redan spenderad i kopian, men som inte var markerad som spenderad här." -#: ../../../ui.cpp:2296 +#: ../../../ui.cpp:2302 msgid "Waiting for confirmation..." msgstr "Väntar på bekräftelse..." -#: ../../../ui.cpp:2314 +#: ../../../ui.cpp:2320 msgid "" "The payment was sent, but the recipient was unable to verify it.\n" "The transaction is recorded and will credit to the recipient,\n" @@ -613,84 +594,84 @@ "Transaktionen är registrerad och kommer att kreditera mottagaren,\n" "men kommentar informationen kommer att vara tom." -#: ../../../ui.cpp:2323 +#: ../../../ui.cpp:2329 msgid "Payment was sent, but an invalid response was received" msgstr "Betalning var skickad, men en ogiltig respons var mottagen" -#: ../../../ui.cpp:2329 +#: ../../../ui.cpp:2335 msgid "Payment completed" msgstr "Betalning slutförd" -#: ../../../ui.cpp:2371 -#: ../../../ui.cpp:2517 -#: ../../../ui.cpp:2554 +#: ../../../ui.cpp:2377 +#: ../../../ui.cpp:2525 +#: ../../../ui.cpp:2565 msgid "Name" msgstr "Namn" -#: ../../../ui.cpp:2372 -#: ../../../ui.cpp:2517 -#: ../../../ui.cpp:2554 +#: ../../../ui.cpp:2378 +#: ../../../ui.cpp:2525 +#: ../../../ui.cpp:2565 msgid "Address" msgstr "Adress" -#: ../../../ui.cpp:2374 -#: ../../../ui.cpp:2529 +#: ../../../ui.cpp:2380 +#: ../../../ui.cpp:2537 msgid "Label" msgstr "Etikett" -#: ../../../ui.cpp:2375 +#: ../../../ui.cpp:2381 #: ../../../uibase.cpp:837 msgid "Bitcoin Address" msgstr "Bitcoin Adress" -#: ../../../ui.cpp:2499 +#: ../../../ui.cpp:2507 msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " msgstr "Denna är en av dina egna adresser för mottagning av betalningar och kan inte slås in i adressboken. " -#: ../../../ui.cpp:2517 -#: ../../../ui.cpp:2523 +#: ../../../ui.cpp:2525 +#: ../../../ui.cpp:2531 msgid "Edit Address" msgstr "Ändra Adress" -#: ../../../ui.cpp:2529 +#: ../../../ui.cpp:2537 msgid "Edit Address Label" msgstr "Ändra Address Etikett" -#: ../../../ui.cpp:2554 -#: ../../../ui.cpp:2560 +#: ../../../ui.cpp:2565 +#: ../../../ui.cpp:2571 msgid "Add Address" msgstr "Lägg till Adress" -#: ../../../ui.cpp:2637 +#: ../../../ui.cpp:2649 msgid "Bitcoin" msgstr "Bitcoin" -#: ../../../ui.cpp:2639 +#: ../../../ui.cpp:2651 msgid "Bitcoin - Generating" msgstr "Bitcoin - Genererar" -#: ../../../ui.cpp:2641 +#: ../../../ui.cpp:2653 msgid "Bitcoin - (not connected)" msgstr "Bitcoin - (ej ansluten)" -#: ../../../ui.cpp:2720 +#: ../../../ui.cpp:2732 msgid "&Open Bitcoin" msgstr "&Öppna Bitcoin" -#: ../../../ui.cpp:2721 +#: ../../../ui.cpp:2733 msgid "&Send Bitcoins" msgstr "&Skicka Bitcoins" -#: ../../../ui.cpp:2722 +#: ../../../ui.cpp:2734 msgid "O&ptions..." msgstr "&Inställningar..." -#: ../../../ui.cpp:2725 +#: ../../../ui.cpp:2737 #: ../../../uibase.cpp:25 msgid "E&xit" msgstr "&Avsluta" -#: ../../../ui.cpp:2951 +#: ../../../ui.cpp:2963 msgid "Program has crashed and will terminate. " msgstr "Programmet har krachat och kommer att avslutas. " @@ -791,7 +772,6 @@ msgstr "&Minimerar till systemfältet istället för aktivitetsfält" #: ../../../uibase.cpp:351 -#, fuzzy msgid "Map port using &UPnP" msgstr "Mapp port använder &UPnP" @@ -812,9 +792,8 @@ msgstr " &Port:" #: ../../../uibase.cpp:392 -#, fuzzy msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." -msgstr "Frivillig transaktionsavgift per KB som garanterar att din transaktion bearbetas snabbt. Flesta transaktioner är 1KB. Most transactions are 1KB. Avgift 0.01 rekommenderas." +msgstr "Frivillig transaktionsavgift per KB som garanterar att din transaktion bearbetas snabbt. Flesta transaktioner är 1KB. Avgift 0.01 rekommenderas." #: ../../../uibase.cpp:399 msgid "Pay transaction fee:" @@ -850,7 +829,6 @@ msgstr "version" #: ../../../uibase.cpp:525 -#, fuzzy msgid "" "Copyright (c) 2009-2011 Bitcoin Developers\n" "\n" @@ -865,14 +843,16 @@ msgstr "" "Copyright (c) 2009-2011 Bitcoin Developers\n" "\n" -"This is experimental software.\n" +"Detta är en experimentell mjukvara.\n" +"\n" +"Distribuerad under MIT/X11 mjukvarulicens, se medföljande fil \n" +"license.txt eller http://www.opensource.org/licenses/mit-license.php.\n" "\n" -"Distributed under the MIT/X11 software license, see the accompanying file \n" -"license.txt or http://www.opensource.org/licenses/mit-license.php.\n" +"Denna produkt inkluderar mjukvara utvecklad av OpenSSL Project för användning i \n" +"OpenSSL Toolkit (http://www.openssl.org/) och kryptografisk mjukvara skriven av \n" +"Eric Young (eay@cryptsoft.com) och UPnP mjukvara skriven av Thomas Bernard.\n" "\n" -"This product includes software developed by the OpenSSL Project for use in the \n" -"OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \n" -"Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard." +"Översatt av Han Lin Yap." #: ../../../uibase.cpp:581 msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" @@ -895,9 +875,8 @@ msgstr "&Belopp:" #: ../../../uibase.cpp:630 -#, fuzzy msgid "T&ransfer:" -msgstr "T&ransfer:" +msgstr "&Överföring:" #: ../../../uibase.cpp:636 msgid " Standard" @@ -918,9 +897,8 @@ "Ansluter..." #: ../../../uibase.cpp:761 -#, fuzzy msgid "These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window." -msgstr "Dessa är dina Bitcoin adresser för mottagning av betalningar. Du rekommenderas att ge olika till varje avsändare så du kan ha koll på vem som betalar dig. Den markerade adressen är visar i huvudfönstret." +msgstr "Dessa är dina Bitcoin adresser för mottagning av betalningar. Du rekommenderas att ge olika till varje avsändare så du kan ha koll på vem som betalar dig. Den markerade adressen visas i huvudfönstret." #: ../../../uibase.cpp:774 #: ../../../uibase.cpp:886 @@ -937,9 +915,8 @@ msgstr "Skickar" #: ../../../uibase.cpp:857 -#, fuzzy msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." -msgstr "Dessa är dina Bitcoin adresser för mottagning av betalningar. Du kan ge olika till varje avsändare så du kan ha koll på vem som betalar dig. Den markerade adressen är visar i huvudfönstret." +msgstr "Dessa är dina Bitcoin adresser för mottagning av betalningar. Du kan ge olika till varje avsändare så du kan ha koll på vem som betalar dig. Den markerade adressen visas i huvudfönstret." #: ../../../uibase.cpp:870 msgid "Receiving" @@ -949,15 +926,35 @@ msgid "&Delete" msgstr "&Ta bort" -#: ../../../util.cpp:866 -#, fuzzy +#: ../../../util.cpp:874 msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." -msgstr "Varning: Var god och kolla att din dator har rätt datum och klockslag. Om din klocka är fel så kommer Bitcoin inte att fungera." +msgstr "Varning: Var god och kolla att din dator har rätt datum och klockslag. Om din klocka är fel så kommer Bitcoin inte att fungera ordentligt." -#: ../../../util.cpp:899 +#: ../../../util.cpp:908 msgid "beta" msgstr "beta" +#: ../../../wallet.cpp:917 +#, c-format +msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " +msgstr "Fel: Denna transaktion kräver en transaktionsavgift minst %s för dess belopp, komplexitet, eller användning av nyligen mottagna pengar " + +#: ../../../wallet.cpp:919 +msgid "Error: Transaction creation failed " +msgstr "Fel: Misslyckades att skapa transaktion " + +#: ../../../wallet.cpp:928 +msgid "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." +msgstr "Fel: Transaktionen blev nekad. Detta kan hända om några av dina mynt i din plånbok var redan spenderad. Till exempel om du använde en kopia av wallet.dat och mynten var redan spenderad i kopian, men som inte var markerad som spenderad här." + +#: ../../../wallet.cpp:941 +msgid "Invalid amount" +msgstr "Ogiltig belopp" + +#: ../../../wallet.cpp:948 +msgid "Invalid bitcoin address" +msgstr "Ogiltig bitcoin adress" + #: ../../../uibase.h:147 msgid "Transaction Details" msgstr "Transaktion detaljer" @@ -974,5 +971,3 @@ msgid "Your Bitcoin Addresses" msgstr "Dina Bitcoin Adresser" -#~ msgid " beta" -#~ msgstr " beta"
index cdec9a037b1736061d63f5bf0e1563eda8f38529..734d21701edfa77de2e7ebcf44ba2e838f030eb3 GIT binary patch literal 93256 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
}+E5aq0UjuB(Z6K#YUq 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%0D-^{~dl8bU8dLh=1aBz^#3gS?y=QGpQ9Ko9{a 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	OZd)pT=$+Yb+6`rg$r(ftwm=JMLyOMBWERVEd2 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 UNbR?-*1z*>EBH)sik#g40Z(BFC;$Ke
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9ab0ce2591d21cce2408983986b7c97c2d1c476f GIT binary patch literal 25818 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 Oz<>b*1`HVZaQH9ne%5aQ
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..71255c6850b00ef1efea82fefd05ff736c90f816 GIT binary patch literal 154542 zc%1EBdvq1mxu^ZZ)eGTecm*ymLBOT0aJ5#^g`$G5(kj+kY_(MGQfsfhzFMiRSFMVo zNeF~P9zbG39wZ?^fDqmR0*OE%JdzN?BM^uogph<JXZFmVnRCBAhlH5N$vMf)nb-GQ zKU`J<o!P&=zu&j_?EURWXRZDHk9#rP2frr4uLSrt^+&yW{ixTlUd;&X<NnnQ7XpDm zAP@)y0)apv5C{YUfj}S-2m}IwKp+qZ1OkCTAP@)y0)apv5C{YUfj}S-2t+FgqFhhp z)7PXu<zjk?7;%Jtv0r$1hcI^&|KfUnMlzY6NT$Sa6QexwXDhfz64_6_u$KShMjrn7 zXZwWke40`$W}g>Ju1a-8CZeqOyV?sJl`mbFb1sT8$LOay!mFA5%w%%sa&GK0Zg{v> z9OK|7MRAWN5$FaV?G;uWrMu3H7wRP^MfKGL3|kO4>#VrwAbmZHpO!$zMQA9i_q;8F zn;K8%W%3L2giWW#@_Gpeem4O6o~n@&3h9Ttg(p+U_(=Vg^+tLa`0wo$;IZN1IUMpH zak)`mUn+vW5SAfq>Mmcm2@n5p0{I|YNIfZ5G@$4=AWCv^wG>rAU*5n&j-<Oxs&hgl zHz$L49HvFp61=S5?X3ggtqZHAu!D3~nz@It_Z;ou;AP>J3vDC%xmq@gf0af?+e6|G zMTggiMu4W!TMbRnB*^PdiIBA#B#Slzp(&t2pjn`C^wvimfE_Q$6<~Uzd)pe8&^TY_ z3Z*q>9p+$3+soKM)^wG_N`zV4pSSRP%Aw^<Gt40(r4)-`NxHY5NeNAtULqQNQLc{2 z(FJr`0;;S6XC#w^LJCc)x2kR7R{23RWwi-S3JqIt48<FGR9SOEs7xxNI<C7y3bDGF zKAwas`-wA?$;Q*7|ApRlUVJVcRn~zouH*AA`Du1ma#ebBE3f-2+nFQ6xp#I5Wpx@V z?iA#(gLIM=zfhQwcdz6iQxY`zXbyAyCst$7HXNT_L%yp}ZGcxb%JZ`Y-CqjX8Amy| zfA15naXlU2o6m?3t-|4K0zQ&RAYtyF$~8{;A2^)NMi}4?yl(@1|3wk{iSAF1>;|7o zA^DYFIk+gvOAb-nZX~b<$47Ee1=O?9<@M6b8*uJy5x$YdLtfpX&@ijIKMv!zr8q5t z9Q?j*JYQabaod`Ncpi8BMm%p4<o9=CzHM>N&lWf;&&E#}_TX>VVJ3z|B9TZW5{X12 zkw_#Gi9{liNF)-8L?V$$Boe7UgY<p?q^1m7!VO)*1%`2bL%4y9xM555e<Y-eWcn`V zZe7F$1UuoMqaEy^)8BRp35Dz=%b+m*pAgv-{y^U_Rw!)7YW~CBH1(u-szxTw2ioAj z1O)5<w8-ueT)1yYTYbywWTB(;OlwLc_(?QwGZOrF%rfqSU7qx9jj}q|*a#K@bboTB zuN<<N8yCr4Y3f4a7KpNIW-@_LultiDTiD{i{X#v3T=*@>vDcjPp@PIe(6SA{_W9LQ zDf}B-gpm$Ua)WRnpZ8j$W$Q%``7`)0l~~lhH<t4-QG!1UVcGjqKxo<im$);1+viuW zW%2z&I{m9aHP8+e^b%;<eib^LCC@Xvnjf_wszB`9xz_NvL5G3J?5)^n*?#1}Mcl8~ z@PgL`dk$ZgM}&J?-bBkbEMcN_M>M(W^i~=tWtKg-bB9ICHY~xcLGG>Re5k~QmTg`_ z)LoG4L)1mfHZKQ+a=%&Y!!<={+2$pf?_JBe8qQm3(6Y@-7@@%Ia<pt)5Tb6#0kmve zuzx7`QikBYG-%o8C9~`mXxX;l4a>e@ILi)Fo^7b|QD$%$>q0PVfd5}`kbn?p?{99h zPp}jIBm5TpKwubKG=M)9gxeQ8q7f{+PcTy!WCF3kRzSXfp-i$-4t9y{J+b8JRQ{z5 z{>`nz`@4ks*);e74Qb{lIrP1q0{qtR*7MU7$)sp*q=WU1KFXd(rn}xPY#i!t*{LU` zpM1j<xjmBYHJ!VO|2T&(KT5Zrla5`HFE_fH1Q+$L@9?6lmUA7gl9P)?=mXEBu^VGy zybn-%j_ysZJ9W40%0^eradF>8>2l-Ey{4)Fp5aWb9Ct!|VI2>H9m3HNdnX3ETeg32 zv`U(vElh|aptzmKxVn}NEeXGySfs-(gk9qFHTmrw6#Di+yDs4L+_K%7)xc1;%Vo$C zw##M3F(Yd2#@=#idLj=U(uSvvx@XytGrM=GLB<P0LjpW|Ex#a_ZZDIraV`z6p;HsJ z91L)Q<!m-{@NQT(WXrcKWaIalR30+ktg}*8lgrrhc7Vl)DD+hid8Q@lt7Ye0lpwz? ztCI~re!E2c2@w(uTgmOKWm^f+1tRk!+jzIHmTfUC%%kjVi`C^0Qf5go2kHHdbBizA z&#VM0x&E-h)1rZ?3CY-CrO*LH?~zNnhY|?nrN^rLbWytjaj8L`ypr5%l_CJclqAIc zwP?gr_D$i<Ekf)u@x&FG_>h-b7U`!%NXyOptpxNP6m~=3Aa)5mnU^U<7SQ}ksmZ3f zm?tQa+^M^2zK!3oo8$N1Sf=lie42YnswaB4rm;~_C5?0#eSxLDzOQBB`0Wnf*&%pX z?MHpBgkx7^XiP&*w_*B^`f7wfWeNtFe+4N^AAipl4x_%>V9Qwv653&U3+*QKy07xA zGfk3ZwtWctEu@YuY@)6%ODbsuCv`oziUb;CuB{x;Ay=Br_u&C#Z4_LmYUHf5Qsfb~ zGY~vzb~^u95&=J&5XHWY0w+ds_r;N!t9h6N{c8`6J0TWTcU?_OMSQlO8YhhR3w1^n zm}5y3#65hOeHR1Oo=fK^uOy=#Y;Oakl<qB~0~fLMW011rw}pe6w+aUYJK>)&6?!a* zUvh|^uk%L_KU66PdE7$jPeMC9oIupwjHe=MI9K)sDeNGfyGfX`lKkgVrWz<aQ2Aaw zbct`x=w7skSBCB}A&M->r478cii4+2OE5|pAEwB?>5PHIzRtV$Uy{P}>6{GyuH{Tk z7?S-%nYhE$+ouhGTR;f+crss9t!+#<)LAnyl;3CYn!c}>$S4)(WeWGi5~VOH`<^mn zv9<vaBL5xH<WQxCa<4CC*|<TL$KCV&BbW96IQ7?ULaznR!5Zt^hR~xRovUcjDwtoq z?iy#Lvt|&@{<c&9Id+;($1UOY=WW)?xvAuW*?~bUd$?j=lcF{3+g?Ji<CgBPczesW zifpfE8D#;jxo<ne^L5V9bgYm7>A|a+T1B?6@+iz5beFh=fs44Q@kIB<QoXWPNCIz< z;wl?8d8zml;sB2|mi^2irJ~W=Q#ucAy(%QQD_U<jt;y?eJ}YTGq41Rh7IDv~^Kw_F zEl6ygxsGUZC_~2z3B7}zJ{4;79=pq>ARm`~w5I#uMqWh+DGEnjC$7k`$Hf2LF3eob zj-pS9;$|lE@r5ckj=q-t*X^2kSoQ_OY3+XBzihqnzP!jjE+iI;Z*3DEh$kbLvZ*Ni z00`k;YG#YfA>3#CRhC;X%ZAsPqs^L<F|~%^2?I9vxcJdt`bZ-CxG+#zJsuR+aUBWx zkI(@!POCXv(aW;oMdog@k=DbNa<T)J+V6p#=-a-DW~FuQ^4>!)%kIOfc4!jA(@u(p zEy?B6Q$c?i7r|9DsMa!iS$6*rE=HT<-r@NM`ux$ujsX#VqpD%t|CSA5WR!y|zN*Q} zA*4VC+*8^;LiGD2N6ie)|Ca6k*r$ckFhzyT$2jZZJtV~2U#1fCTDE&Ve2+Hk;U}tP zn8Fw^G3y?|vd2f7*s>umwaheCN7x~1nE*cA<d)qplzVU$sc~xJ)Es32+%m^D-889X z!-R243@N^<)z{4RrRF}f*&)qn*$`Uq{gxDICNvRUk0uf8)j%_sWxEUI{W6s=({kr9 zOshR#7i&_Q#j@R>Zb9phbEu{t>yKZNAubKJmQ%OT_?8{Gh#B;gDg6G6+HRz*C2Wrw zbSm9N(TIk%Z1)O31npnMkyR%|?{9?c9t6qt@&>^gi=v&;fR;T}sp}FL#?JM`924s` zKIP$3godelzYq)BbZZ*NvWGSg<Z%()D;tH)XCyDH#P<*oy60}PzR+&!XxTx^C?25f zrWom91x~{c(=*rnw+p)Tn*4MM4?WWkLJ#-5WxLPf4N?lM!9cz(f_pBVUv!8TR?Cuq zx4N%ACEdB4^tWy@)}9(!cI%HsK}&Ax>n@=8Ks<SSyO3DKYS{Y!FhfOy{LT&v&tsV{ zSzb~L%YJ{S&|4`j?%pi}p<}dzZDoIJ+l>NxPMs=4)Dssxz~mTW&vNm@HLz?Lu>C^W zF1T4~{QvEx$;Dzxjm+s?`GXf-U*=Kh+yC(mJHl^ItyQ<|swR0ynN-<mtQzBx4>Sp` z3-xmR32}BhKU~@EU^m58w`^13;P=vhZx%pn3$K;6rxuoN7VNtyJ)O#GN*k(#ou*XX zvP}dcy1vMzgOw6Jx(ne4s&3h)Lq@51TZApHU$>`aw?R(1G(N)mlWsd(c57@sCk_j@ z{^gr?w(QnecEnhx?6n|Tb_?dLH`yHlz7j3F1*fmc<07nlO`CBn8zw>5dA4?4Rwox< zl`9)%_;)Au>rIXea@i(B-9^!k{<myNW}4<#N+~DBuk+|z+l1e);~z;RcP%Fqqu9QM zG0WJk_Y<Spr?KbP@_*k&-CxJFez2-0*B#Ns!b96XmJP%9Os$-DQv5iFKAX<}bOozV z3;)->gPnatSOu8C=CZ>>m0Gne#fRNr&EN;XYhKwX>^iS)2>Rz9>m1c=Pwgz5N-Q9+ zE*9V0DZsFW(Rypx&EmtXKCRbFltIdzs9y;CgRf=^=j*lVnujmT!wpkhT6Jn+*+;9S zf9;`9rSM~yvB4V<%-tyd(Bn2_)r>>9|B5BwbyOOt=YanCcrtI{l{D2YJN7vJ@mDPH zs-kau_7CMIM3SOvO-A>^JWCzeY(v#8yQD@Qy-eFfUXU<9k-|3$>dU>mTpVV|3OTA! zb<6fcje;PhG;8!x^$!eOby_(a*TS+P9}Cbp5<)nFNm--Xr@bJ)J-ddt-m%RVs&3gy zMdCn>Pc#SJxEDkHB<+3Zs75L{tS(iz>{HrXHV`uW`5M$ZQ;J_%R%<g_HV{I`tTbNr z-Hb*qYS(kREnD4M&3>?K$e@0@f@@H_Vx?h=RjS24-#9<tXEMtkvY6f3r}{PDme+bf zDEFJSYR*^vVA(^I8oYI=weRgVDVnQlQmw`OVA&AEC&zHAPrG(oUF#s_>(bV9X0q)5 zN-c5K*Uq+=Nfur@a}%a8U#fb&g4UJ|Go!FW>VJGsD760eGkC%0(@kU95QWAr<IdKq zza;+oeq&wUq*3dc$g;I78vpVJ!Sd(vO=Q^+g6@waS2^_ubuDpCUTNh`hAlLOW#7uS zB#}ekYqDJ->#Tt;%+-{}w`_RAaS<d(vs*R)XPcF`oVBKrEjvirfOL;$8;}6y_433h z>!0^&X-{KX_N`%TM9<3<E?(Dg&+ErIb{W)e8qKo7J)x`I7e`W0YFoAvrf-l2*dZ%x zp+PKrm{QfSUkEojh6Ep=H5#PcZSbc|-ca{n`+@peHkb&EEEve}7>_6O(MQFr+T8ol z1__1YK&!8nb=cbew`}(vJpoDu+PhbhcXzNO9{wp$>S9L#Bo@7`e&W7E`p2?|DMQ$O z(<}VXsqy69ox+Avu~zMGl%4^}-p{`!1FXB5&@(l%?7@p~7Ow28l=+>!lFZ#GEXk(_ zDkNPB-&Hiok0tTeKA!2BT3Gh|@uYV!D_r?NJb67!h&)1bFG;FzDe(zsYUSyPysai# z?Wu)jr<X{p3Pl*;dKD&ZgWL*fN(`~{h;AWR_7`ejk8T{q92ZABEO<{-H?<DoAQ{$M z6ZLWFy8P!Y0!**$nRR!_KEYhb0jrJcv=VWOQe0Y#)1xLOGzH9ax1Q6#j*411S|$Hs z13Or4`LcDs5{&HrIQ5Uk>4I~0@(0;;l!G1P#o^qBgO%F;8KtHl)S&W5d+CHI7PS3# zNw--Tq!iYMC>K>=Zl^x@z4XowVL}vJv9Za=XfJtVEjpO(?Rhkb-&SVU5e=rZu2g(+ zJwIY8s{8|eTh^lC-|vYfFc31&NW8{38)^YbW*;v;-AC{HmQ9)a+x1?L)@;2NJ)(In zIy|55zbIW-`>3Pekabp?nM{;{>|}caZLcyA#2uwvqV(ogA+mtxSDIMg)^HrAw=Bfe z>n0&w-@TF)ROx?-lIl27EstD^LHi~lOBolzX;<z~M-b5k!OAArc6h@eWqBm2$OMU( zD7&CfRyO+3E#I=uj&3g*5W>B;)1V7sFgDBT<kXYmM|<frX*@WNPfPLN9v3Zt{K_W= zhH=xAh+vqhbCbX(N-@X8w|B70v}2nq)3W-dA>5n{AG#%4b{j&bIyQnUtJ6+B9}s#_ zylVxUD7h#2Z7S2kxV~!zSHpSxx1nXXVURMk*OVAyV1K@!-tx7R>D$qxx@#I_U+^Kj zK+A5!0Cr&65R)#@(Q}cC03W}e$D(EbkYI%~lZm>O-z3>}rOCD9ycAVHy`Q{8e1<6P z;WP~h_mVG`efY9G!n!ryyFs-q8xp*8b#i)%_(=}^^%{PXQk8c=D3@R9gF%3l9!8?C zmhGgjdt+^JK;BCRDW@H~XW6oH^-0z_38qCel3Bt3z~&1bhA0<0fL%rv_~5V*q9IUs z_Nd*k?ANkvcN)txeX{HpeHY}?*=u3^GFkhEuxU~Ig8$IY(AwThqq=27Ps8-AHM_Lz z4)qOy@f&(${C4&?L;Qp&>iyntv}~=}p=Ebl-`0d5gQkWC_g)>eY)$E|ufA5<OV)FJ z+Yl|=XdD#AJ+Yd9DMKB7TN5qYXdIy|pbbz--`0d)^ouxxvuryM8hNCHJK@W<S!mhj zB?$NJakOk(5bW};Z9YU@v~2SdEPHA^Azlwe)h)Z|syxcUmU?t=3d@sO_EOy}yGd~E zyC~friCX)Kezt7TH@{MfETFGt3HQdbYqfQ60sGKb%kJ{7()O0!Mql@d9(Fr+7*4qS zN?$EoxvSLE*(>Ez51~<T9l4D98jHSKwk*4zPZtJsZrMRg*c!e&KBK-yqpz0zb)F~7 z9_~JAi253mzFKz1X%S*L9=kImy|L_i;>x`wh3C_`8-=@95)|5`?98%T>pL0rRU$zD zP&^cGZuSr1RuzgK^c}4BS2m<x3}j!)3Cxcs$DqCzr~4~8>Wf4okw_#Gi9{liNF)-8 zL?V$$Bob*c{%$?5`!gW@z}e}9i1PewLH8#?YRdO_3Qf&7(8e97<0JKdB&6yb?ckQT zyC3J^_tLZkqWiNURpf*5WN&%L8!M|C<u|g>zAeI6HuB~5T~v^ZD!_PdZjNzq;rZSk z70<7fo=U-ZZc09uL=IH=RuHm*m;b#F^K+B&pL>LBTsKSl?m90%l86J`1bk=}*?gv_ zx2QlrfdM|sq5tb3JL8ADg)2>}Rp|b%LV9)$4sgTqiPdCJC$p-aKoI5V0($pK{a+9X zoD{{9Z70?6rn9m-cFFGuz2DU4{L5DU^ff<Sn38u%dT|}Dy6C{?(lrU%U1H;Dab_}_ zxSu#9nWUW*C0V!YDLE=96;WJB*OU*&lNCp)Q!vCOr1gZQZBye>arIS(hOHxpP`NeW zk>ZZi85q^oAcRU|s@xhd3rH^!f0c%ccazX`DaB%wF(S4%fD{7K#n-a<+m`9ydZysm zW$Z44?PVgQUwW(8O_bJ1U*-yE<sJx)vmjR}t~SI4qdf;iq;;pnd71pU2>sjEAcUrX z27zWVQMmRA=W5w~mtaYw?fNkVUL0N@8UdO@Z#Db@u%yCjDeNGfWgF4QI5>D&cx8BT z^Ez@*0B>DXEjbR;IT`!}D{g$67{$H3frr`CsT!L~+#xC&<kXYm2id~I31p0!2Rmfc zGn2`OyM^_o;^juv*AqA@!zf57r0?w%9!(;*nIWAUAIUwL!t_llqNlG(g1UEm+XF<D z%j>0#QgLCP09h+cPYfbGWYN<S$m?1BqJuQ+ta$0VjQXkzCzUVMOS{gCD~{5S_6mR8 z$iu(~Pt-K#LrlJNISb3LX7Zor2r<WK&P66Jr{z8YM0>!%uW`yJud)sR@iRQ1ezs3| zcL(bRFRW!f0o)&yg8txvQ)0O3i3EQ5#dZALO+5VZFZK(NF{YP@d&@<L$@K(>Edqf+ zAP@)y0)apv5C{YUfj}S-2m}IwKp+qZ1OkCTAP@)y0)apv5C{YUfj}S-h_?8Dw5>;g
--- a/share/setup.nsi +++ b/share/setup.nsi @@ -1,15 +1,20 @@ Name Bitcoin RequestExecutionLevel highest +SetCompressor /SOLID lzma # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" -!define VERSION 0.3.24 +!define VERSION 0.3.25 !define COMPANY "Bitcoin project" !define URL http://www.bitcoin.org/ # MUI Symbol Definitions !define MUI_ICON "../share/pixmaps/bitcoin.ico" +!define MUI_WELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp" +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_RIGHT +!define MUI_HEADERIMAGE_BITMAP "../share/pixmaps/nsis-header.bmp" !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM !define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} @@ -17,6 +22,7 @@ !define MUI_STARTMENUPAGE_DEFAULTFOLDER Bitcoin !define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin.exe !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp" !define MUI_UNFINISHPAGE_NOAUTOCLOSE # Included files @@ -39,12 +45,13 @@ !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile bitcoin-0.3.24-win32-setup.exe +OutFile bitcoin-0.3.25-win32-setup.exe InstallDir $PROGRAMFILES\Bitcoin CRCCheck on XPStyle on +BrandingText " " ShowInstDetails show -VIProductVersion 0.3.24.0 +VIProductVersion 0.3.25.0 VIAddVersionKey ProductName Bitcoin VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey CompanyName "${COMPANY}"
--- a/share/uiproject.fbp +++ b/share/uiproject.fbp @@ -167,6 +167,36 @@ <property name="checked">0</property> <property name="enabled">1</property> <property name="help"></property> + <property name="id">wxID_ANY</property> + <property name="kind">wxITEM_NORMAL</property> + <property name="label">&Encrypt Wallet...</property> + <property name="name">m_menuOptionsEncryptWallet</property> + <property name="permission">public</property> + <property name="shortcut"></property> + <property name="unchecked_bitmap"></property> + <event name="OnMenuSelection">OnMenuOptionsEncryptWallet</event> + <event name="OnUpdateUI"></event> + </object> + <object class="wxMenuItem" expanded="1"> + <property name="bitmap"></property> + <property name="checked">0</property> + <property name="enabled">1</property> + <property name="help"></property> + <property name="id">wxID_ANY</property> + <property name="kind">wxITEM_NORMAL</property> + <property name="label">&Change Wallet Encryption Passphrase...</property> + <property name="name">m_menuOptionsChangeWalletPassphrase</property> + <property name="permission">public</property> + <property name="shortcut"></property> + <property name="unchecked_bitmap"></property> + <event name="OnMenuSelection">OnMenuOptionsChangeWalletPassphrase</event> + <event name="OnUpdateUI"></event> + </object> + <object class="wxMenuItem" expanded="1"> + <property name="bitmap"></property> + <property name="checked">0</property> + <property name="enabled">1</property> + <property name="help"></property> <property name="id">wxID_PREFERENCES</property> <property name="kind">wxITEM_NORMAL</property> <property name="label">&Options...</property>
--- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -36,6 +36,9 @@ typedef Value(*rpcfn_type)(const Array& params, bool fHelp); extern map<string, rpcfn_type> mapCallTable; +static int64 nWalletUnlockTime; +static CCriticalSection cs_nWalletUnlockTime; + Object JSONRPCError(int code, const string& message) { @@ -309,7 +312,10 @@ obj.push_back(Pair("hashespersec", gethashespersec(params, false))); obj.push_back(Pair("testnet", fTestNet)); obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); + obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize())); obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); + if (pwalletMain->IsCrypted()) + obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime)); obj.push_back(Pair("errors", GetWarnings("statusbar"))); return obj; } @@ -324,13 +330,19 @@ "If [account] is specified (recommended), it is added to the address book " "so payments received with the address will be credited to [account]."); + if (!pwalletMain->IsLocked()) + pwalletMain->TopUpKeyPool(); + + if (pwalletMain->GetKeyPoolSize() < 1) + throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); + // 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]); // Generate a new key that is added to wallet - string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool()); + string strAddress = PubKeyToAddress(pwalletMain->GetOrReuseKeyFromPool()); // This could be done in the same main CS as GetKeyFromKeyPool. CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) @@ -346,37 +358,48 @@ string strAddress; CWalletDB walletdb(pwalletMain->strWalletFile); - walletdb.TxnBegin(); CAccount account; - walletdb.ReadAccount(strAccount, account); - - // Check if the current key has been used - if (!account.vchPubKey.empty()) + CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) { - CScript scriptPubKey; - scriptPubKey.SetBitcoinAddress(account.vchPubKey); - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); - it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty(); - ++it) + walletdb.ReadAccount(strAccount, account); + + bool bKeyUsed = false; + + // Check if the current key has been used + if (!account.vchPubKey.empty()) { - const CWalletTx& wtx = (*it).second; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (txout.scriptPubKey == scriptPubKey) - account.vchPubKey.clear(); + CScript scriptPubKey; + scriptPubKey.SetBitcoinAddress(account.vchPubKey); + for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); + it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty(); + ++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.empty() || bForceNew || bKeyUsed) + { + if (pwalletMain->GetKeyPoolSize() < 1) + { + if (bKeyUsed || bForceNew) + throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first"); + } + else + { + account.vchPubKey = pwalletMain->GetOrReuseKeyFromPool(); + string strAddress = PubKeyToAddress(account.vchPubKey); + pwalletMain->SetAddressBookName(strAddress, strAccount); + walletdb.WriteAccount(strAccount, account); + } } } - // Generate a new key - if (account.vchPubKey.empty() || bForceNew) - { - account.vchPubKey = pwalletMain->GetKeyFromKeyPool(); - string strAddress = PubKeyToAddress(account.vchPubKey); - pwalletMain->SetAddressBookName(strAddress, strAccount); - walletdb.WriteAccount(strAccount, account); - } - - walletdb.TxnCommit(); strAddress = PubKeyToAddress(account.vchPubKey); return strAddress; @@ -510,7 +533,12 @@ Value sendtoaddress(const Array& params, bool fHelp) { - if (fHelp || params.size() < 2 || params.size() > 4) + if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4)) + throw runtime_error( + "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n" + "<amount> is a real and is rounded to the nearest 0.00000001\n" + "requires wallet passphrase to be set with walletpassphrase first"); + if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4)) throw runtime_error( "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n" "<amount> is a real and is rounded to the nearest 0.00000001"); @@ -528,7 +556,11 @@ wtx.mapValue["to"] = params[3].get_str(); CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) { + if(pwalletMain->IsLocked()) + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + string strError = pwalletMain->SendMoneyToBitcoinAddress(strAddress, nAmount, wtx); if (strError != "") throw JSONRPCError(-4, strError); @@ -674,7 +706,7 @@ Value getbalance(const Array& params, bool fHelp) { - if (fHelp || params.size() < 0 || params.size() > 2) + if (fHelp || params.size() > 2) throw runtime_error( "getbalance [account] [minconf=1]\n" "If [account] is not specified, returns the server's total available balance.\n" @@ -733,9 +765,9 @@ string strFrom = AccountFromValue(params[0]); string strTo = AccountFromValue(params[1]); int64 nAmount = AmountFromValue(params[2]); - int nMinDepth = 1; if (params.size() > 3) - nMinDepth = params[3].get_int(); + // 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(); @@ -773,7 +805,12 @@ Value sendfrom(const Array& params, bool fHelp) { - if (fHelp || params.size() < 3 || params.size() > 6) + if (pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6)) + throw runtime_error( + "sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n" + "<amount> is a real and is rounded to the nearest 0.00000001\n" + "requires wallet passphrase to be set with walletpassphrase first"); + if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6)) throw runtime_error( "sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n" "<amount> is a real and is rounded to the nearest 0.00000001"); @@ -794,7 +831,11 @@ CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) { + if(pwalletMain->IsLocked()) + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + // Check funds int64 nBalance = GetAccountBalance(strAccount, nMinDepth); if (nAmount > nBalance) @@ -809,9 +850,15 @@ return wtx.GetHash().GetHex(); } + Value sendmany(const Array& params, bool fHelp) { - if (fHelp || params.size() < 2 || params.size() > 4) + if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4)) + throw runtime_error( + "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n" + "amounts are double-precision floating point numbers\n" + "requires wallet passphrase to be set with walletpassphrase first"); + if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4)) throw runtime_error( "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n" "amounts are double-precision floating point numbers"); @@ -851,7 +898,11 @@ CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) { + if(pwalletMain->IsLocked()) + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + // Check funds int64 nBalance = GetAccountBalance(strAccount, nMinDepth); if (totalAmount > nBalance) @@ -1281,6 +1332,219 @@ } +Value keypoolrefill(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() > 0)) + throw runtime_error( + "keypoolrefill\n" + "Fills the keypool, requires wallet passphrase to be set."); + if (!pwalletMain->IsCrypted() && (fHelp || params.size() > 0)) + throw runtime_error( + "keypoolrefill\n" + "Fills the keypool."); + + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) + { + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); + + pwalletMain->TopUpKeyPool(); + } + + if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100)) + throw JSONRPCError(-4, "Error refreshing keypool."); + + return Value::null; +} + + +void ThreadTopUpKeyPool(void* parg) +{ + pwalletMain->TopUpKeyPool(); +} + +void ThreadCleanWalletPassphrase(void* parg) +{ + int64 nMyWakeTime = GetTime() + *((int*)parg); + + if (nWalletUnlockTime == 0) + { + CRITICAL_BLOCK(cs_nWalletUnlockTime) + { + nWalletUnlockTime = nMyWakeTime; + } + + while (GetTime() < nWalletUnlockTime) + Sleep(GetTime() - nWalletUnlockTime); + + CRITICAL_BLOCK(cs_nWalletUnlockTime) + { + nWalletUnlockTime = 0; + } + } + else + { + CRITICAL_BLOCK(cs_nWalletUnlockTime) + { + if (nWalletUnlockTime < nMyWakeTime) + nWalletUnlockTime = nMyWakeTime; + } + free(parg); + return; + } + + pwalletMain->Lock(); + + delete (int*)parg; +} + +Value walletpassphrase(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + throw runtime_error( + "walletpassphrase <passphrase> <timeout>\n" + "Stores the wallet decryption key in memory for <timeout> seconds."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrase was called."); + + if (!pwalletMain->IsLocked()) + throw JSONRPCError(-17, "Error: Wallet is already unlocked."); + + // Note that the walletpassphrase is stored in params[0] which is not mlock()ed + string strWalletPass; + strWalletPass.reserve(100); + mlock(&strWalletPass[0], strWalletPass.capacity()); + strWalletPass = params[0].get_str(); + + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) + { + if (strWalletPass.length() > 0) + { + if (!pwalletMain->Unlock(strWalletPass)) + { + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + } + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + } + else + throw runtime_error( + "walletpassphrase <passphrase> <timeout>\n" + "Stores the wallet decryption key in memory for <timeout> seconds."); + } + + CreateThread(ThreadTopUpKeyPool, NULL); + int* pnSleepTime = new int(params[1].get_int()); + CreateThread(ThreadCleanWalletPassphrase, pnSleepTime); + + return Value::null; +} + + +Value walletpassphrasechange(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + throw runtime_error( + "walletpassphrasechange <oldpassphrase> <newpassphrase>\n" + "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); + + string strOldWalletPass; + strOldWalletPass.reserve(100); + mlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + strOldWalletPass = params[0].get_str(); + + string strNewWalletPass; + strNewWalletPass.reserve(100); + mlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + strNewWalletPass = params[1].get_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)) + { + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + } + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + + return Value::null; +} + + +Value walletlock(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) + throw runtime_error( + "walletlock\n" + "Removes the wallet encryption key from memory, locking the wallet.\n" + "After calling this method, you will need to call walletpassphrase again\n" + "before being able to call any methods which require the wallet to be unlocked."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called."); + + pwalletMain->Lock(); + CRITICAL_BLOCK(cs_nWalletUnlockTime) + { + nWalletUnlockTime = 0; + } + + return Value::null; +} + + +Value encryptwallet(const Array& params, bool fHelp) +{ + if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) + throw runtime_error( + "encryptwallet <passphrase>\n" + "Encrypts the wallet with <passphrase>."); + if (fHelp) + return true; + if (pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called."); + + string strWalletPass; + strWalletPass.reserve(100); + mlock(&strWalletPass[0], strWalletPass.capacity()); + strWalletPass = params[0].get_str(); + + if (strWalletPass.length() < 1) + throw runtime_error( + "encryptwallet <passphrase>\n" + "Encrypts the wallet with <passphrase>."); + + if (!pwalletMain->EncryptWallet(strWalletPass)) + { + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + throw JSONRPCError(-16, "Error: Failed to encrypt the wallet."); + } + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + + return Value::null; +} + + Value validateaddress(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1432,44 +1696,49 @@ pair<string, rpcfn_type> pCallTable[] = { - make_pair("help", &help), - make_pair("stop", &stop), - make_pair("getblockcount", &getblockcount), - make_pair("getblocknumber", &getblocknumber), - make_pair("getconnectioncount", &getconnectioncount), - make_pair("getdifficulty", &getdifficulty), - make_pair("getgenerate", &getgenerate), - make_pair("setgenerate", &setgenerate), - make_pair("gethashespersec", &gethashespersec), - make_pair("getinfo", &getinfo), - make_pair("getnewaddress", &getnewaddress), - make_pair("getaccountaddress", &getaccountaddress), - make_pair("setaccount", &setaccount), - make_pair("setlabel", &setaccount), // deprecated - make_pair("getaccount", &getaccount), - make_pair("getlabel", &getaccount), // deprecated - make_pair("getaddressesbyaccount", &getaddressesbyaccount), - make_pair("getaddressesbylabel", &getaddressesbyaccount), // deprecated - make_pair("sendtoaddress", &sendtoaddress), - make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress - make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress - make_pair("getreceivedbyaddress", &getreceivedbyaddress), - make_pair("getreceivedbyaccount", &getreceivedbyaccount), - make_pair("getreceivedbylabel", &getreceivedbyaccount), // deprecated - make_pair("listreceivedbyaddress", &listreceivedbyaddress), - make_pair("listreceivedbyaccount", &listreceivedbyaccount), - make_pair("listreceivedbylabel", &listreceivedbyaccount), // deprecated - make_pair("backupwallet", &backupwallet), - make_pair("validateaddress", &validateaddress), - make_pair("getbalance", &getbalance), - make_pair("move", &movecmd), - make_pair("sendfrom", &sendfrom), - make_pair("sendmany", &sendmany), - make_pair("gettransaction", &gettransaction), - make_pair("listtransactions", &listtransactions), - make_pair("getwork", &getwork), - make_pair("listaccounts", &listaccounts), - make_pair("settxfee", &settxfee), + make_pair("help", &help), + make_pair("stop", &stop), + make_pair("getblockcount", &getblockcount), + make_pair("getblocknumber", &getblocknumber), + make_pair("getconnectioncount", &getconnectioncount), + make_pair("getdifficulty", &getdifficulty), + make_pair("getgenerate", &getgenerate), + make_pair("setgenerate", &setgenerate), + make_pair("gethashespersec", &gethashespersec), + make_pair("getinfo", &getinfo), + make_pair("getnewaddress", &getnewaddress), + make_pair("getaccountaddress", &getaccountaddress), + make_pair("setaccount", &setaccount), + make_pair("setlabel", &setaccount), // deprecated + make_pair("getaccount", &getaccount), + make_pair("getlabel", &getaccount), // deprecated + make_pair("getaddressesbyaccount", &getaddressesbyaccount), + make_pair("getaddressesbylabel", &getaddressesbyaccount), // deprecated + make_pair("sendtoaddress", &sendtoaddress), + make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress + make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress + make_pair("getreceivedbyaddress", &getreceivedbyaddress), + make_pair("getreceivedbyaccount", &getreceivedbyaccount), + make_pair("getreceivedbylabel", &getreceivedbyaccount), // deprecated + make_pair("listreceivedbyaddress", &listreceivedbyaddress), + make_pair("listreceivedbyaccount", &listreceivedbyaccount), + make_pair("listreceivedbylabel", &listreceivedbyaccount), // deprecated + make_pair("backupwallet", &backupwallet), + make_pair("keypoolrefill", &keypoolrefill), + make_pair("walletpassphrase", &walletpassphrase), + make_pair("walletpassphrasechange", &walletpassphrasechange), + make_pair("walletlock", &walletlock), + make_pair("encryptwallet", &encryptwallet), + make_pair("validateaddress", &validateaddress), + make_pair("getbalance", &getbalance), + make_pair("move", &movecmd), + make_pair("sendfrom", &sendfrom), + make_pair("sendmany", &sendmany), + make_pair("gettransaction", &gettransaction), + make_pair("listtransactions", &listtransactions), + make_pair("getwork", &getwork), + make_pair("listaccounts", &listaccounts), + make_pair("settxfee", &settxfee), }; map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); @@ -1493,6 +1762,9 @@ "getaddressesbyaccount", "getaddressesbylabel", // deprecated "backupwallet", + "keypoolrefill", + "walletpassphrase", + "walletlock", "validateaddress", "getwork", }; @@ -2130,6 +2402,7 @@ if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]); if (strMethod == "listtransactions" && n > 2) ConvertTo<boost::int64_t>(params[2]); if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]); + if (strMethod == "walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]); if (strMethod == "sendmany" && n > 1) { string s = params[1].get_str(); @@ -2146,7 +2419,6 @@ // Parse reply const Value& result = find_value(reply, "result"); const Value& error = find_value(reply, "error"); - const Value& id = find_value(reply, "id"); if (error.type() != null_type) {
new file mode 100644 --- /dev/null +++ b/src/crypter.cpp @@ -0,0 +1,132 @@ +// Copyright (c) 2011 The Bitcoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <openssl/aes.h> +#include <openssl/evp.h> +#include <vector> +#include <string> +#include "headers.h" +#ifdef __WXMSW__ +#include <windows.h> +#endif + +#include "crypter.h" +#include "main.h" +#include "util.h" + +bool CCrypter::SetKeyFromPassphrase(const std::string& 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; + + // Try to keep the keydata out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap) + // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) + // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process. + mlock(&chKey[0], sizeof chKey); + mlock(&chIV[0], sizeof chIV); + + int i = 0; + if (nDerivationMethod == 0) + i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], + (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); + + if (i != WALLET_CRYPTO_KEY_SIZE) + { + memset(&chKey, 0, sizeof chKey); + memset(&chIV, 0, sizeof chIV); + return false; + } + + fKeySet = true; + return true; +} + +bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV) +{ + if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE) + return false; + + // Try to keep the keydata out of swap + // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) + // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process. + mlock(&chKey[0], sizeof chKey); + mlock(&chIV[0], sizeof chIV); + + memcpy(&chKey[0], &chNewKey[0], sizeof chKey); + memcpy(&chIV[0], &chNewIV[0], sizeof chIV); + + fKeySet = true; + return true; +} + +bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<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; + + EVP_CIPHER_CTX_init(&ctx); + EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); + + EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen); + EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen); + + EVP_CIPHER_CTX_cleanup(&ctx); + + 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; + + EVP_CIPHER_CTX_init(&ctx); + EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); + + EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen); + EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen); + + EVP_CIPHER_CTX_cleanup(&ctx); + + vchPlaintext.resize(nPLen + nFLen); + return true; +} + + +bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &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((CKeyingMaterial)vchPlaintext, vchCiphertext); +} + +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CSecret& 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)); +}
new file mode 100644 --- /dev/null +++ b/src/crypter.h @@ -0,0 +1,96 @@ +// Copyright (c) 2011 The Bitcoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef __CRYPTER_H__ +#define __CRYPTER_H__ + +#include "key.h" + +const unsigned int WALLET_CRYPTO_KEY_SIZE = 32; +const unsigned int WALLET_CRYPTO_SALT_SIZE = 8; + +/* +Private key encryption is done based on a CMasterKey, +which holds a salt and random encryption key. + +CMasterKeys is 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 private key as the IV, and the +master key's key as the encryption key. +*/ + +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; + + IMPLEMENT_SERIALIZE + ( + READWRITE(vchCryptedKey); + READWRITE(vchSalt); + READWRITE(nDerivationMethod); + READWRITE(nDeriveIterations); + READWRITE(vchOtherDerivationParameters); + ) + CMasterKey() + { + // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M + // ie slightly lower than the lowest hardware we need bother supporting + nDeriveIterations = 25000; + nDerivationMethod = 0; + vchOtherDerivationParameters = std::vector<unsigned char>(0); + } +}; + +typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial; + +class CCrypter +{ +private: + unsigned char chKey[WALLET_CRYPTO_KEY_SIZE]; + unsigned char chIV[WALLET_CRYPTO_KEY_SIZE]; + bool fKeySet; + +public: + bool SetKeyFromPassphrase(const std::string &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() + { + memset(&chKey, 0, sizeof chKey); + memset(&chIV, 0, sizeof chIV); + munlock(&chKey, sizeof chKey); + munlock(&chIV, sizeof chIV); + fKeySet = false; + } + + CCrypter() + { + fKeySet = false; + } + + ~CCrypter() + { + CleanKey(); + } +}; + +bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext); +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char> &vchCiphertext, const uint256& nIV, CSecret &vchPlaintext); + +#endif
--- a/src/cryptopp/cpu.cpp +++ b/src/cryptopp/cpu.cpp @@ -80,7 +80,7 @@ #endif } -#ifndef _MSC_VER +#if !CRYPTOPP_BOOL_X64 && !defined(_MSC_VER) && defined(__GNUC__) static jmp_buf s_jmpNoSSE2; static void SigIllHandlerSSE2(int) {
--- a/src/db.cpp +++ b/src/db.cpp @@ -627,8 +627,6 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& entries) { - int64 nCreditDebit = 0; - bool fAllAccounts = (strAccount == "*"); Dbc* pcursor = GetCursor(); @@ -670,7 +668,7 @@ } -bool CWalletDB::LoadWallet(CWallet* pwallet) +int CWalletDB::LoadWallet(CWallet* pwallet) { pwallet->vchDefaultKey.clear(); int nFileVersion = 0; @@ -685,12 +683,12 @@ //// todo: shouldn't we catch exceptions and try to recover and continue? CRITICAL_BLOCK(pwallet->cs_mapWallet) - CRITICAL_BLOCK(pwallet->cs_mapKeys) + CRITICAL_BLOCK(pwallet->cs_KeyStore) { // Get cursor Dbc* pcursor = GetCursor(); if (!pcursor) - return false; + return DB_CORRUPT; loop { @@ -701,7 +699,7 @@ if (ret == DB_NOTFOUND) break; else if (ret != 0) - return false; + return DB_CORRUPT; // Unserialize // Taking advantage of the fact that pair serialization @@ -765,14 +763,42 @@ { vector<unsigned char> vchPubKey; ssKey >> vchPubKey; - CWalletKey wkey; + CKey key; if (strType == "key") - ssValue >> wkey.vchPrivKey; + { + CPrivKey pkey; + ssValue >> pkey; + key.SetPrivKey(pkey); + } else + { + CWalletKey wkey; ssValue >> wkey; - - pwallet->mapKeys[vchPubKey] = wkey.vchPrivKey; - mapPubKeys[Hash160(vchPubKey)] = vchPubKey; + key.SetPrivKey(wkey.vchPrivKey); + } + if (!pwallet->LoadKey(key)) + return DB_CORRUPT; + } + else if (strType == "mkey") + { + unsigned int nID; + ssKey >> nID; + CMasterKey kMasterKey; + ssValue >> kMasterKey; + if(pwallet->mapMasterKeys.count(nID) != 0) + return DB_CORRUPT; + 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; + if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey)) + return DB_CORRUPT; } else if (strType == "defaultkey") { @@ -800,7 +826,6 @@ if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; #endif if (strKey == "nTransactionFee") ssValue >> nTransactionFee; - if (strKey == "addrIncoming") ssValue >> addrIncoming; if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors; if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors; if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray; @@ -809,6 +834,13 @@ if (strKey == "addrProxy") ssValue >> addrProxy; if (fHaveUPnP && strKey == "fUseUPnP") ssValue >> fUseUPnP; } + else if (strType == "minversion") + { + int nMinVersion = 0; + ssValue >> nMinVersion; + if (nMinVersion > VERSION) + return DB_TOO_NEW; + } } pcursor->close(); } @@ -819,7 +851,6 @@ printf("nFileVersion = %d\n", nFileVersion); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); printf("nTransactionFee = %"PRI64d"\n", nTransactionFee); - printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); printf("fMinimizeToTray = %d\n", fMinimizeToTray); printf("fMinimizeOnClose = %d\n", fMinimizeOnClose); printf("fUseProxy = %d\n", fUseProxy); @@ -839,7 +870,7 @@ } - return true; + return DB_LOAD_OK; } void ThreadFlushWalletDB(void* parg)
--- a/src/db.h +++ b/src/db.h @@ -88,7 +88,7 @@ if (!pdb) return false; if (fReadOnly) - assert(("Write called on database in read-only mode", false)); + assert(!"Write called on database in read-only mode"); // Key CDataStream ssKey(SER_DISK); @@ -117,7 +117,7 @@ if (!pdb) return false; if (fReadOnly) - assert(("Erase called on database in read-only mode", false)); + assert(!"Erase called on database in read-only mode"); // Key CDataStream ssKey(SER_DISK); @@ -342,6 +342,14 @@ +enum DBErrors +{ + DB_LOAD_OK, + DB_CORRUPT, + DB_TOO_NEW, + DB_LOAD_FAIL, +}; + class CWalletDB : public CDB { public: @@ -391,6 +399,25 @@ return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false); } + bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true) + { + nWalletDBUpdated++; + 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 WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); + } + bool WriteBestBlock(const CBlockLocator& locator) { nWalletDBUpdated++; @@ -450,7 +477,7 @@ int64 GetAccountCreditDebit(const std::string& strAccount); void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries); - bool LoadWallet(CWallet* pwallet); + int LoadWallet(CWallet* pwallet); }; #endif
--- a/src/init.cpp +++ b/src/init.cpp @@ -386,8 +386,16 @@ nStart = GetTimeMillis(); bool fFirstRun; pwalletMain = new CWallet("wallet.dat"); - if (!pwalletMain->LoadWallet(fFirstRun)) - strErrors += _("Error loading wallet.dat \n"); + int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun); + if (nLoadWalletRet != DB_LOAD_OK) + { + if (nLoadWalletRet == DB_CORRUPT) + strErrors += _("Error loading wallet.dat: Wallet corrupted \n"); + else if (nLoadWalletRet == DB_TOO_NEW) + strErrors += _("Error loading wallet.dat: Wallet requires newer version of Bitcoin \n"); + else + strErrors += _("Error loading wallet.dat \n"); + } printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); RegisterWallet(pwalletMain); @@ -415,7 +423,6 @@ //// debug print printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); printf("nBestHeight = %d\n", nBestHeight); - printf("mapKeys.size() = %d\n", pwalletMain->mapKeys.size()); printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size()); printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
--- a/src/key.h +++ b/src/key.h @@ -31,6 +31,41 @@ // see www.keylength.com // script supports up to 75 for single byte push +int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) +{ + int ok = 0; + BN_CTX *ctx = NULL; + EC_POINT *pub_key = NULL; + + if (!eckey) return 0; + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + pub_key = EC_POINT_new(group); + + if (pub_key == NULL) + goto err; + + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) + goto err; + + EC_KEY_set_private_key(eckey,priv_key); + EC_KEY_set_public_key(eckey,pub_key); + + ok = 1; + +err: + + if (pub_key) + EC_POINT_free(pub_key); + if (ctx != NULL) + BN_CTX_free(ctx); + + return(ok); +} class key_error : public std::runtime_error @@ -42,8 +77,7 @@ // secure_allocator is defined in serialize.h typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; - - +typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret; class CKey { @@ -102,6 +136,38 @@ return true; } + bool SetSecret(const CSecret& vchSecret) + { + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed"); + if (vchSecret.size() != 32) + throw key_error("CKey::SetSecret() : secret must be 32 bytes"); + BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new()); + if (bn == NULL) + throw key_error("CKey::SetSecret() : BN_bin2bn failed"); + if (!EC_KEY_regenerate_key(pkey,bn)) + throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed"); + BN_clear_free(bn); + fSet = true; + return true; + } + + CSecret GetSecret() const + { + CSecret vchRet; + vchRet.resize(32); + const BIGNUM *bn = EC_KEY_get0_private_key(pkey); + int nBytes = BN_num_bytes(bn); + if (bn == NULL) + throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed"); + int n=BN_bn2bin(bn,&vchRet[32 - nBytes]); + if (n != nBytes) + throw key_error("CKey::GetSecret(): BN_bn2bin failed"); + return vchRet; + } + CPrivKey GetPrivKey() const { unsigned int nSize = i2d_ECPrivateKey(pkey, NULL); @@ -154,22 +220,6 @@ return false; return true; } - - static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, std::vector<unsigned char>& vchSig) - { - CKey key; - if (!key.SetPrivKey(vchPrivKey)) - return false; - return key.Sign(hash, vchSig); - } - - static bool Verify(const std::vector<unsigned char>& vchPubKey, uint256 hash, const std::vector<unsigned char>& vchSig) - { - CKey key; - if (!key.SetPubKey(vchPubKey)) - return false; - return key.Verify(hash, vchSig); - } }; #endif
--- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -4,13 +4,7 @@ #include "headers.h" #include "db.h" - - - -////////////////////////////////////////////////////////////////////////////// -// -// mapKeys -// +#include "crypter.h" std::vector<unsigned char> CKeyStore::GenerateNewKey() { @@ -18,13 +12,14 @@ CKey key; key.MakeNewKey(); if (!AddKey(key)) - throw std::runtime_error("GenerateNewKey() : AddKey failed"); + throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed"); return key.GetPubKey(); } -bool CKeyStore::AddKey(const CKey& key) +bool CBasicKeyStore::AddKey(const CKey& key) { - CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_mapPubKeys) + CRITICAL_BLOCK(cs_KeyStore) { mapKeys[key.GetPubKey()] = key.GetPrivKey(); mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey(); @@ -32,3 +27,121 @@ return true; } +std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey() +{ + RandAddSeedPerfmon(); + CKey key; + key.MakeNewKey(); + if (!AddKey(key)) + throw std::runtime_error("CCryptoKeyStore::GenerateNewKey() : AddKey failed"); + return key.GetPubKey(); +} + +bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) +{ + CRITICAL_BLOCK(cs_vMasterKey) + { + if (!SetCrypted()) + return false; + + std::map<std::vector<unsigned char>, std::vector<unsigned char> >::const_iterator mi = mapCryptedKeys.begin(); + for (; mi != mapCryptedKeys.end(); ++mi) + { + const std::vector<unsigned char> &vchPubKey = (*mi).first; + const std::vector<unsigned char> &vchCryptedSecret = (*mi).second; + CSecret vchSecret; + if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret)) + return false; + CKey key; + key.SetSecret(vchSecret); + if (key.GetPubKey() == vchPubKey) + break; + return false; + } + vMasterKey = vMasterKeyIn; + } + return true; +} + +bool CCryptoKeyStore::AddKey(const CKey& key) +{ + CRITICAL_BLOCK(cs_KeyStore) + CRITICAL_BLOCK(cs_vMasterKey) + { + if (!IsCrypted()) + return CBasicKeyStore::AddKey(key); + + if (IsLocked()) + return false; + + std::vector<unsigned char> vchCryptedSecret; + std::vector<unsigned char> vchPubKey = key.GetPubKey(); + if (!EncryptSecret(vMasterKey, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret)) + return false; + + if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) + return false; + } + return true; +} + + +bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) +{ + CRITICAL_BLOCK(cs_mapPubKeys) + CRITICAL_BLOCK(cs_KeyStore) + { + if (!SetCrypted()) + return false; + + mapCryptedKeys[vchPubKey] = vchCryptedSecret; + mapPubKeys[Hash160(vchPubKey)] = vchPubKey; + } + return true; +} + +bool CCryptoKeyStore::GetPrivKey(const std::vector<unsigned char> &vchPubKey, CKey& keyOut) const +{ + CRITICAL_BLOCK(cs_vMasterKey) + { + if (!IsCrypted()) + return CBasicKeyStore::GetPrivKey(vchPubKey, keyOut); + + std::map<std::vector<unsigned char>, std::vector<unsigned char> >::const_iterator mi = mapCryptedKeys.find(vchPubKey); + if (mi != mapCryptedKeys.end()) + { + const std::vector<unsigned char> &vchCryptedSecret = (*mi).second; + CSecret vchSecret; + if (!DecryptSecret(vMasterKey, (*mi).second, Hash((*mi).first.begin(), (*mi).first.end()), vchSecret)) + return false; + keyOut.SetSecret(vchSecret); + return true; + } + } + return false; +} + +bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) +{ + CRITICAL_BLOCK(cs_KeyStore) + CRITICAL_BLOCK(cs_vMasterKey) + { + if (!mapCryptedKeys.empty() || IsCrypted()) + return false; + + fUseCrypto = true; + CKey key; + BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys) + { + if (!key.SetPrivKey(mKey.second)) + return false; + std::vector<unsigned char> vchCryptedSecret; + if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(mKey.first.begin(), mKey.first.end()), vchCryptedSecret)) + return false; + if (!AddCryptedKey(mKey.first, vchCryptedSecret)) + return false; + } + mapKeys.clear(); + } + return true; +}
--- a/src/keystore.h +++ b/src/keystore.h @@ -4,27 +4,112 @@ #ifndef BITCOIN_KEYSTORE_H #define BITCOIN_KEYSTORE_H +#include "crypter.h" + class CKeyStore { public: - std::map<std::vector<unsigned char>, CPrivKey> mapKeys; - mutable CCriticalSection cs_mapKeys; - virtual bool AddKey(const CKey& key); + mutable CCriticalSection cs_KeyStore; + + virtual bool AddKey(const CKey& key) =0; + virtual bool HaveKey(const std::vector<unsigned char> &vchPubKey) const =0; + virtual bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CKey& keyOut) const =0; + virtual std::vector<unsigned char> GenerateNewKey(); +}; + +typedef std::map<std::vector<unsigned char>, CPrivKey> KeyMap; + +class CBasicKeyStore : public CKeyStore +{ +protected: + KeyMap mapKeys; + +public: + bool AddKey(const CKey& key); bool HaveKey(const std::vector<unsigned char> &vchPubKey) const { return (mapKeys.count(vchPubKey) > 0); } - bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CPrivKey& keyOut) const + bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CKey& keyOut) const { std::map<std::vector<unsigned char>, CPrivKey>::const_iterator mi = mapKeys.find(vchPubKey); if (mi != mapKeys.end()) { - keyOut = (*mi).second; + keyOut.SetPrivKey((*mi).second); return true; } return false; } +}; + +class CCryptoKeyStore : public CBasicKeyStore +{ +private: + std::map<std::vector<unsigned char>, std::vector<unsigned char> > mapCryptedKeys; + + CKeyingMaterial vMasterKey; + + // if fUseCrypto is true, mapKeys must be empty + // if fUseCrypto is false, vMasterKey must be empty + bool fUseCrypto; + +protected: + bool SetCrypted() + { + if (fUseCrypto) + return true; + if (!mapKeys.empty()) + return false; + fUseCrypto = true; + return true; + } + + // will encrypt previously unencrypted keys + bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); + + bool Unlock(const CKeyingMaterial& vMasterKeyIn); + +public: + mutable CCriticalSection cs_vMasterKey; //No guarantees master key wont get locked before you can use it, so lock this first + + CCryptoKeyStore() : fUseCrypto(false) + { + } + + bool IsCrypted() const + { + return fUseCrypto; + } + + bool IsLocked() const + { + if (!IsCrypted()) + return false; + return vMasterKey.empty(); + } + + bool Lock() + { + CRITICAL_BLOCK(cs_vMasterKey) + { + if (!SetCrypted()) + return false; + + vMasterKey.clear(); + } + return true; + } + + virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); std::vector<unsigned char> GenerateNewKey(); + bool AddKey(const CKey& key); + bool HaveKey(const std::vector<unsigned char> &vchPubKey) const + { + if (!IsCrypted()) + return CBasicKeyStore::HaveKey(vchPubKey); + return mapCryptedKeys.count(vchPubKey) > 0; + } + bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CKey& keyOut) const; }; #endif
--- a/src/main.cpp +++ b/src/main.cpp @@ -55,7 +55,6 @@ // Settings int fGenerateBitcoins = false; int64 nTransactionFee = 0; -CAddress addrIncoming; int fLimitProcessors = false; int nLimitProcessors = 1; int fMinimizeToTray = true; @@ -1689,7 +1688,7 @@ return strStatusBar; else if (strFor == "rpc") return strRPC; - assert(("GetWarnings() : invalid parameter", false)); + assert(!"GetWarnings() : invalid parameter"); return "error"; } @@ -1900,6 +1899,8 @@ return error("message addr size() = %d", vAddr.size()); // Store the new addresses + CAddrDB addrDB; + addrDB.TxnBegin(); int64 nNow = GetAdjustedTime(); int64 nSince = nNow - 10 * 60; BOOST_FOREACH(CAddress& addr, vAddr) @@ -1911,7 +1912,7 @@ continue; if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) addr.nTime = nNow - 5 * 24 * 60 * 60; - AddAddress(addr, 2 * 60 * 60); + AddAddress(addr, 2 * 60 * 60, &addrDB); pfrom->AddAddressKnown(addr); if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) { @@ -1942,6 +1943,7 @@ } } } + addrDB.TxnCommit(); // Save addresses (it's ok if this fails) if (vAddr.size() < 1000) pfrom->fGetAddr = false; } @@ -2213,7 +2215,7 @@ // Keep giving the same key to the same ip until they use it if (!mapReuseKey.count(pfrom->addr.ip)) - mapReuseKey[pfrom->addr.ip] = pwalletMain->GetKeyFromKeyPool(); + mapReuseKey[pfrom->addr.ip] = pwalletMain->GetOrReuseKeyFromPool(); // Send back approval of order and pubkey to use CScript scriptPubKey;
--- a/src/main.h +++ b/src/main.h @@ -70,7 +70,6 @@ // Settings extern int fGenerateBitcoins; extern int64 nTransactionFee; -extern CAddress addrIncoming; extern int fLimitProcessors; extern int nLimitProcessors; extern int fMinimizeToTray;
--- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -4,6 +4,8 @@ DEPSDIR:=/usr/i586-mingw32msvc +USE_UPNP:=0 + INCLUDEPATHS= \ -I"$(DEPSDIR)/boost_1_43_0" \ -I"$(DEPSDIR)/db-4.7.25.NC/build_unix" \ @@ -34,23 +36,15 @@ DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h init.h + script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \ + crypter.h init.h -bitcoin.exe: USE_UPNP:=1 - ifdef USE_UPNP - INCLUDEPATHS += -I"$(DEPSDIR)/upnpc-exe-win32-20110215" - LIBPATHS += -L"$(DEPSDIR)/upnpc-exe-win32-20110215" - LIBS += -l miniupnpc -l iphlpapi - DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) - endif - -bitcoind.exe: USE_UPNP:=0 - ifdef USE_UPNP - INCLUDEPATHS += -I"$(DEPSDIR)/upnpc-exe-win32-20110215" - LIBPATHS += -L"$(DEPSDIR)/upnpc-exe-win32-20110215" - LIBS += -l miniupnpc -l iphlpapi - DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) - endif +ifdef USE_UPNP + INCLUDEPATHS += -I"$(DEPSDIR)/upnpc-exe-win32-20110215" + LIBPATHS += -L"$(DEPSDIR)/upnpc-exe-win32-20110215" + LIBS += -l miniupnpc -l iphlpapi + DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) +endif LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi @@ -65,6 +59,7 @@ obj/wallet.o \ obj/rpc.o \ obj/init.o \ + obj/crypter.o \ cryptopp/obj/sha.o \ cryptopp/obj/cpu.o
--- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -33,7 +33,8 @@ DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h init.h + script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \ + init.h crypter.h ifdef USE_UPNP INCLUDEPATHS += -I"C:\upnpc-exe-win32-20110215" @@ -55,6 +56,7 @@ obj/wallet.o \ obj/rpc.o \ obj/init.o \ + obj/crypter.o \ cryptopp/obj/sha.o \ cryptopp/obj/cpu.o
--- a/src/makefile.osx +++ b/src/makefile.osx @@ -33,7 +33,8 @@ # ppc doesn't work because we don't support big-endian CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O3 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h init.h + script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \ + init.h crypter.h OBJS= \ obj/util.o \ @@ -46,6 +47,7 @@ obj/wallet.o \ obj/rpc.o \ obj/init.o \ + obj/crypter.o \ cryptopp/obj/sha.o \ cryptopp/obj/cpu.o
--- a/src/makefile.unix +++ b/src/makefile.unix @@ -39,7 +39,8 @@ DEBUGFLAGS=-g -D__WXDEBUG__ CXXFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h init.h + script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \ + init.h crypter.h OBJS= \ obj/util.o \ @@ -52,6 +53,7 @@ obj/wallet.o \ obj/rpc.o \ obj/init.o \ + obj/crypter.o \ cryptopp/obj/sha.o \ cryptopp/obj/cpu.o
--- a/src/net.cpp +++ b/src/net.cpp @@ -440,7 +440,7 @@ -bool AddAddress(CAddress addr, int64 nTimePenalty) +bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB) { if (!addr.IsRoutable()) return false; @@ -455,7 +455,10 @@ // New address printf("AddAddress(%s)\n", addr.ToString().c_str()); mapAddresses.insert(make_pair(addr.GetKey(), addr)); - CAddrDB().WriteAddress(addr); + if (pAddrDB) + pAddrDB->WriteAddress(addr); + else + CAddrDB().WriteAddress(addr); return true; } else @@ -477,7 +480,12 @@ fUpdated = true; } if (fUpdated) - CAddrDB().WriteAddress(addrFound); + { + if (pAddrDB) + pAddrDB->WriteAddress(addrFound); + else + CAddrDB().WriteAddress(addrFound); + } } } return false; @@ -831,7 +839,7 @@ { BOOST_FOREACH(CNode* pnode, vNodes) { - if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0) + if (pnode->hSocket == INVALID_SOCKET) continue; FD_SET(pnode->hSocket, &fdsetRecv); FD_SET(pnode->hSocket, &fdsetError); @@ -1158,6 +1166,8 @@ if (!fTestNet) { printf("Loading addresses from DNS seeds (could take a while)\n"); + CAddrDB addrDB; + addrDB.TxnBegin(); for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) { vector<CAddress> vaddr; @@ -1168,12 +1178,14 @@ if (addr.GetByte(3) != 127) { addr.nTime = 0; - AddAddress(addr); + AddAddress(addr, 0, &addrDB); found++; } } } } + + addrDB.TxnCommit(); // Save addresses (it's ok if this fails) } printf("%d addresses found from DNS seeds\n", found); @@ -1700,7 +1712,7 @@ printf("Error: CreateThread(ThreadIRCSeed) failed\n"); // Send and receive from sockets, accept connections - pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true); + CreateThread(ThreadSocketHandler, NULL, true); // Initiate outbound connections if (!CreateThread(ThreadOpenConnections, NULL))
--- a/src/net.h +++ b/src/net.h @@ -15,6 +15,7 @@ class CMessageHeader; class CAddress; +class CAddrDB; class CInv; class CRequestTracker; class CNode; @@ -40,7 +41,7 @@ bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); bool GetMyExternalIP(unsigned int& ipRet); -bool AddAddress(CAddress addr, int64 nTimePenalty=0); +bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL); void AddressCurrentlyConnected(const CAddress& addr); CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
--- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -38,7 +38,7 @@ { cachedAddressTable.clear(); - CRITICAL_BLOCK(wallet->cs_mapKeys) + CRITICAL_BLOCK(cs_mapPubKeys) CRITICAL_BLOCK(wallet->cs_mapAddressBook) { BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item, wallet->mapAddressBook) @@ -255,14 +255,15 @@ { // Generate a new address to associate with given label, optionally // set as default receiving address. - strAddress = PubKeyToAddress(wallet->GetKeyFromKeyPool()); + strAddress = PubKeyToAddress(wallet->GetOrReuseKeyFromPool()); } else { return QString(); } // Add entry and update list - wallet->SetAddressBookName(strAddress, strLabel); + CRITICAL_BLOCK(wallet->cs_mapAddressBook) + wallet->SetAddressBookName(strAddress, strLabel); updateList(); return QString::fromStdString(strAddress); }
--- a/src/script.cpp +++ b/src/script.cpp @@ -580,6 +580,7 @@ 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()); @@ -659,6 +660,7 @@ 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); @@ -1030,7 +1032,7 @@ return false; // Compile solution - CRITICAL_BLOCK(keystore.cs_mapKeys) + CRITICAL_BLOCK(keystore.cs_KeyStore) { BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) { @@ -1038,13 +1040,13 @@ { // Sign const valtype& vchPubKey = item.second; - CPrivKey privkey; - if (!keystore.GetPrivKey(vchPubKey, privkey)) + CKey key; + if (!keystore.GetPrivKey(vchPubKey, key)) return false; if (hash != 0) { vector<unsigned char> vchSig; - if (!CKey::Sign(privkey, hash, vchSig)) + if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)nHashType); scriptSigRet << vchSig; @@ -1057,13 +1059,13 @@ if (mi == mapPubKeys.end()) return false; const vector<unsigned char>& vchPubKey = (*mi).second; - CPrivKey privkey; - if (!keystore.GetPrivKey(vchPubKey, privkey)) + CKey key; + if (!keystore.GetPrivKey(vchPubKey, key)) return false; if (hash != 0) { vector<unsigned char> vchSig; - if (!CKey::Sign(privkey, hash, vchSig)) + if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)nHashType); scriptSigRet << vchSig << vchPubKey; @@ -1089,8 +1091,40 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) { - CScript scriptSig; - return Solver(keystore, scriptPubKey, 0, 0, scriptSig); + vector<pair<opcodetype, valtype> > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + // Compile solution + CRITICAL_BLOCK(keystore.cs_KeyStore) + { + BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_PUBKEY) + { + // Sign + const valtype& vchPubKey = item.second; + if (!keystore.HaveKey(vchPubKey)) + return false; + } + else if (item.first == OP_PUBKEYHASH) + { + // Sign and give pubkey + map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second)); + if (mi == mapPubKeys.end()) + return false; + const vector<unsigned char>& vchPubKey = (*mi).second; + if (!keystore.HaveKey(vchPubKey)) + return false; + } + else + { + return false; + } + } + } + + return true; }
--- a/src/script.h +++ b/src/script.h @@ -486,7 +486,7 @@ { // 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", false)); + assert(!"warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate"); return *this; }
--- a/src/serialize.h +++ b/src/serialize.h @@ -28,12 +28,36 @@ #if defined(_MSC_VER) && _MSC_VER < 1300 #define for if (false) ; else for #endif + +#ifdef __WXMSW__ +// This is used to attempt to keep keying material out of swap +// Note that VirtualLock does not provide this as a guarantee on Windows, +// but, in practice, memory that has been VirtualLock'd almost never gets written to +// the pagefile except in rare circumstances where memory is extremely low. +#define mlock(p, n) VirtualLock((p), (n)); +#define munlock(p, n) VirtualUnlock((p), (n)); +#else +#include <sys/mman.h> +#include <limits.h> +/* This comes from limits.h if it's not defined there set a sane default */ +#ifndef PAGESIZE +#include <unistd.h> +#define PAGESIZE sysconf(_SC_PAGESIZE) +#endif +#define mlock(a,b) \ + mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\ + (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1)))) +#define munlock(a,b) \ + munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\ + (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1)))) +#endif + class CScript; class CDataStream; class CAutoFile; static const unsigned int MAX_SIZE = 0x02000000; -static const int VERSION = 32400; +static const int VERSION = 32500; static const char* pszSubVer = ""; static const bool VERSION_IS_BETA = true; @@ -755,7 +779,8 @@ // -// Allocator that clears its contents before deletion +// 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> @@ -777,10 +802,22 @@ 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) + mlock(p, sizeof(T) * n); + return p; + } + void deallocate(T* p, std::size_t n) { if (p != NULL) + { memset(p, 0, sizeof(T) * n); + munlock(p, sizeof(T) * n); + } std::allocator<T>::deallocate(p, n); } };
--- a/src/ui.cpp +++ b/src/ui.cpp @@ -245,6 +245,41 @@ } } +bool GetWalletPassphrase() +{ + if (pwalletMain->IsLocked()) + { + string strWalletPass; + strWalletPass.reserve(100); + mlock(&strWalletPass[0], strWalletPass.capacity()); + + // obtain current wallet encrypt/decrypt key, from passphrase + // Note that the passphrase is not mlock()d during this entry and could potentially + // be obtained from disk long after bitcoin has run. + strWalletPass = wxGetPasswordFromUser(_("Enter the current passphrase to the wallet."), + _("Passphrase")).ToStdString(); + + if (!strWalletPass.size()) + { + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + wxMessageBox(_("Please supply the current wallet decryption passphrase."), "Bitcoin"); + return false; + } + + if (!pwalletMain->Unlock(strWalletPass)) + { + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin"); + return false; + } + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + } + return true; +} + @@ -333,6 +368,11 @@ if (CWalletDB(pwalletMain->strWalletFile,"r").ReadDefaultKey(vchPubKey)) m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey)); + if (pwalletMain->IsCrypted()) + m_menuOptions->Remove(m_menuOptionsEncryptWallet); + else + m_menuOptions->Remove(m_menuOptionsChangeWalletPassphrase); + // Fill listctrl with wallet transactions RefreshListCtrl(); } @@ -1122,6 +1162,169 @@ return; } +void CMainFrame::OnMenuOptionsEncryptWallet(wxCommandEvent& event) +{ + // Options->Encrypt Wallet + if (pwalletMain->IsCrypted()) + { + wxMessageBox(_("Wallet already encrypted."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } + + string strWalletPass; + strWalletPass.reserve(100); + mlock(&strWalletPass[0], strWalletPass.capacity()); + + // obtain current wallet encrypt/decrypt key, from passphrase + // Note that the passphrase is not mlock()d during this entry and could potentially + // be obtained from disk long after bitcoin has run. + strWalletPass = wxGetPasswordFromUser(_("Enter the new passphrase to the wallet.\nPlease use a passphrase of 10 or more random characters, or eight or more words."), + _("Passphrase")).ToStdString(); + + if (!strWalletPass.size()) + { + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + wxMessageBox(_("Error: The supplied passphrase was too short."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } + + if(wxMessageBox(_("WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\nAre you sure you wish to encrypt your wallet?"), "Bitcoin", wxYES_NO) != wxYES) + return; + + string strWalletPassTest; + strWalletPassTest.reserve(100); + mlock(&strWalletPassTest[0], strWalletPassTest.capacity()); + strWalletPassTest = wxGetPasswordFromUser(_("Please re-enter your new wallet passphrase."), + _("Passphrase")).ToStdString(); + + if (strWalletPassTest != strWalletPass) + { + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + fill(strWalletPassTest.begin(), strWalletPassTest.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + munlock(&strWalletPassTest[0], strWalletPassTest.capacity()); + wxMessageBox(_("Error: the supplied passphrases didn't match."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } + + if (!pwalletMain->EncryptWallet(strWalletPass)) + { + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + fill(strWalletPassTest.begin(), strWalletPassTest.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + munlock(&strWalletPassTest[0], strWalletPassTest.capacity()); + wxMessageBox(_("Wallet encryption failed."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + fill(strWalletPassTest.begin(), strWalletPassTest.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + munlock(&strWalletPassTest[0], strWalletPassTest.capacity()); + wxMessageBox(_("Wallet Encrypted.\nRemember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer."), "Bitcoin"); + + m_menuOptions->Remove(m_menuOptionsEncryptWallet); + m_menuOptions->Insert(m_menuOptions->GetMenuItemCount() - 1, m_menuOptionsChangeWalletPassphrase); +} + +void CMainFrame::OnMenuOptionsChangeWalletPassphrase(wxCommandEvent& event) +{ + // Options->Change Wallet Encryption Passphrase + if (!pwalletMain->IsCrypted()) + { + wxMessageBox(_("Wallet is unencrypted, please encrypt it first."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } + + string strOldWalletPass; + strOldWalletPass.reserve(100); + mlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + + // obtain current wallet encrypt/decrypt key, from passphrase + // Note that the passphrase is not mlock()d during this entry and could potentially + // be obtained from disk long after bitcoin has run. + strOldWalletPass = wxGetPasswordFromUser(_("Enter the current passphrase to the wallet."), + _("Passphrase")).ToStdString(); + + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) + { + bool fWasLocked = pwalletMain->IsLocked(); + pwalletMain->Lock(); + + if (!strOldWalletPass.size() || !pwalletMain->Unlock(strOldWalletPass)) + { + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } + + if (fWasLocked) + pwalletMain->Lock(); + + string strNewWalletPass; + strNewWalletPass.reserve(100); + mlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + + // obtain new wallet encrypt/decrypt key, from passphrase + // Note that the passphrase is not mlock()d during this entry and could potentially + // be obtained from disk long after bitcoin has run. + strNewWalletPass = wxGetPasswordFromUser(_("Enter the new passphrase for the wallet."), + _("Passphrase")).ToStdString(); + + if (!strNewWalletPass.size()) + { + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + wxMessageBox(_("Error: The supplied passphrase was too short."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } + + string strNewWalletPassTest; + strNewWalletPassTest.reserve(100); + mlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); + + // obtain new wallet encrypt/decrypt key, from passphrase + // Note that the passphrase is not mlock()d during this entry and could potentially + // be obtained from disk long after bitcoin has run. + strNewWalletPassTest = wxGetPasswordFromUser(_("Re-enter the new passphrase for the wallet."), + _("Passphrase")).ToStdString(); + + if (strNewWalletPassTest != strNewWalletPass) + { + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); + wxMessageBox(_("Error: the supplied passphrases didn't match."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } + + if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) + { + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); + wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); + wxMessageBox(_("Wallet Passphrase Changed."), "Bitcoin"); + } +} + void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) { // Options->Options @@ -1182,8 +1385,19 @@ return; string strName = dialog.GetValue(); - // Generate new key - string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool()); + string strAddress; + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) + { + bool fWasLocked = pwalletMain->IsLocked(); + if (!GetWalletPassphrase()) + return; + + // Generate new key + strAddress = PubKeyToAddress(pwalletMain->GetOrReuseKeyFromPool()); + + if (fWasLocked) + pwalletMain->Lock(); + } // Save CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) @@ -1947,7 +2161,12 @@ if (fBitcoinAddress) { CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) { + bool fWasLocked = pwalletMain->IsLocked(); + if (!GetWalletPassphrase()) + return; + // Send to bitcoin address CScript scriptPubKey; scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; @@ -1956,13 +2175,22 @@ if (strError == "") wxMessageBox(_("Payment sent "), _("Sending...")); else if (strError == "ABORTED") + { + if (fWasLocked) + pwalletMain->Lock(); return; // leave send dialog open + } else { wxMessageBox(strError + " ", _("Sending...")); EndModal(false); + if (fWasLocked) + pwalletMain->Lock(); return; } + + if (fWasLocked) + pwalletMain->Lock(); } } else @@ -2246,16 +2474,27 @@ Error(_("Insufficient funds")); return; } + CReserveKey reservekey(pwalletMain); int64 nFeeRequired; - if (!pwalletMain->CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired)) + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) { - if (nPrice + nFeeRequired > pwalletMain->GetBalance()) - Error(strprintf(_("This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds"), FormatMoney(nFeeRequired).c_str())); - else - Error(_("Transaction creation failed")); - return; - } + bool fWasLocked = pwalletMain->IsLocked(); + if (!GetWalletPassphrase()) + return; + + if (!pwalletMain->CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired)) + { + if (nPrice + nFeeRequired > pwalletMain->GetBalance()) + Error(strprintf(_("This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds"), FormatMoney(nFeeRequired).c_str())); + else + Error(_("Transaction creation failed")); + return; + } + + if (fWasLocked) + pwalletMain->Lock(); + } // Transaction fee if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this)) @@ -2382,7 +2621,7 @@ m_listCtrlReceiving->SetFocus(); // Fill listctrl with address book data - CRITICAL_BLOCK(pwalletMain->cs_mapKeys) + CRITICAL_BLOCK(pwalletMain->cs_KeyStore) CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) { string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue(); @@ -2581,8 +2820,18 @@ return; strName = dialog.GetValue(); - // Generate new key - strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool()); + CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) + { + bool fWasLocked = pwalletMain->IsLocked(); + if (!GetWalletPassphrase()) + return; + + // Generate new key + strAddress = PubKeyToAddress(pwalletMain->GetOrReuseKeyFromPool()); + + if (fWasLocked) + pwalletMain->Lock(); + } } // Add to list and select it
--- a/src/ui.h +++ b/src/ui.h @@ -59,6 +59,8 @@ void OnMenuFileExit(wxCommandEvent& event); void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event); void OnMenuOptionsChangeYourAddress(wxCommandEvent& event); + void OnMenuOptionsEncryptWallet(wxCommandEvent& event); + void OnMenuOptionsChangeWalletPassphrase(wxCommandEvent& event); void OnMenuOptionsOptions(wxCommandEvent& event); void OnMenuHelpAbout(wxCommandEvent& event); void OnButtonSend(wxCommandEvent& event);
--- a/src/uibase.cpp +++ b/src/uibase.cpp @@ -32,6 +32,12 @@ m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Your Receiving Addresses...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsChangeYourAddress ); + m_menuOptionsEncryptWallet = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Encrypt Wallet...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuOptionsEncryptWallet ); + + m_menuOptionsChangeWalletPassphrase = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Change Wallet Encryption Passphrase...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuOptionsChangeWalletPassphrase ); + wxMenuItem* m_menuOptionsOptions; m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_PREFERENCES, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsOptions ); @@ -187,6 +193,8 @@ this->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) ); this->Connect( m_menuFileExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) ); this->Connect( m_menuOptionsChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); + this->Connect( m_menuOptionsEncryptWallet->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsEncryptWallet ) ); + this->Connect( m_menuOptionsChangeWalletPassphrase->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeWalletPassphrase ) ); this->Connect( m_menuOptionsOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) ); this->Connect( m_menuHelpAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) ); this->Connect( wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) ); @@ -245,6 +253,8 @@ this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsEncryptWallet ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeWalletPassphrase ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) ); this->Disconnect( wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) );
--- a/src/uibase.h +++ b/src/uibase.h @@ -98,6 +98,8 @@ virtual void OnPaint( wxPaintEvent& event ) { event.Skip(); } virtual void OnMenuFileExit( wxCommandEvent& event ) { event.Skip(); } virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ) { event.Skip(); } + virtual void OnMenuOptionsEncryptWallet( wxCommandEvent& event ) { event.Skip(); } + virtual void OnMenuOptionsChangeWalletPassphrase( wxCommandEvent& event ) { event.Skip(); } virtual void OnMenuOptionsOptions( wxCommandEvent& event ) { event.Skip(); } virtual void OnMenuHelpAbout( wxCommandEvent& event ) { event.Skip(); } virtual void OnButtonSend( wxCommandEvent& event ) { event.Skip(); } @@ -115,6 +117,8 @@ public: wxMenu* m_menuOptions; + wxMenuItem* m_menuOptionsEncryptWallet; + wxMenuItem* m_menuOptionsChangeWalletPassphrase; wxStatusBar* m_statusBar; wxTextCtrl* m_textCtrlAddress; wxListCtrl* m_listCtrlAll;
--- a/src/util.cpp +++ b/src/util.cpp @@ -758,8 +758,8 @@ void CreatePidFile(string pidFile, pid_t pid) { - FILE* file; - if (file = fopen(pidFile.c_str(), "w")) + FILE* file = fopen(pidFile.c_str(), "w"); + if (file) { fprintf(file, "%d\n", pid); fclose(file); @@ -788,7 +788,9 @@ fseek(file, -sizeof(pch), SEEK_END); int nBytes = fread(pch, 1, sizeof(pch), file); fclose(file); - if (file = fopen(strFile.c_str(), "w")) + + file = fopen(strFile.c_str(), "w"); + if (file) { fwrite(pch, 1, nBytes, file); fclose(file);
--- a/src/util.h +++ b/src/util.h @@ -262,7 +262,7 @@ // I'd rather be careful than suffer the other more error prone syntax. // The compiler will optimise away all this loop junk. #define CRITICAL_BLOCK(cs) \ - for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ + for (bool fcriticalblockonce=true; fcriticalblockonce; assert("break caught by CRITICAL_BLOCK!" && !fcriticalblockonce), fcriticalblockonce=false) \ for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) class CTryCriticalBlock @@ -276,7 +276,7 @@ }; #define TRY_CRITICAL_BLOCK(cs) \ - for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ + for (bool fcriticalblockonce=true; fcriticalblockonce; assert("break caught by TRY_CRITICAL_BLOCK!" && !fcriticalblockonce), fcriticalblockonce=false) \ for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) @@ -646,7 +646,7 @@ return (pthread_cancel(hthread) == 0); } -inline void ExitThread(unsigned int nExitCode) +inline void ExitThread(size_t nExitCode) { pthread_exit((void*)nExitCode); }
--- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -5,11 +5,11 @@ #include "headers.h" #include "db.h" #include "cryptopp/sha.h" +#include "crypter.h" using namespace std; - ////////////////////////////////////////////////////////////////////////////// // // mapWallet @@ -17,10 +17,181 @@ bool CWallet::AddKey(const CKey& key) { - this->CKeyStore::AddKey(key); + if (!CCryptoKeyStore::AddKey(key)) + return false; + if (!fFileBacked) + return true; + if (!IsCrypted()) + return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey()); + return true; +} + +bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector<unsigned char> &vchCryptedSecret) +{ + if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) + return false; if (!fFileBacked) return true; - return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey()); + CRITICAL_BLOCK(cs_pwalletdbEncryption) + { + if (pwalletdbEncryption) + return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret); + else + return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret); + } +} + +bool CWallet::Unlock(const string& strWalletPassphrase) +{ + CRITICAL_BLOCK(cs_vMasterKey) + { + if (!IsLocked()) + return false; + + CCrypter crypter; + CKeyingMaterial vMasterKey; + + BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (CCryptoKeyStore::Unlock(vMasterKey)) + return true; + } + } + return false; +} + +bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const string& strNewWalletPassphrase) +{ + CRITICAL_BLOCK(cs_vMasterKey) + { + bool fWasLocked = IsLocked(); + + Lock(); + + CCrypter crypter; + CKeyingMaterial vMasterKey; + BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if(!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (CCryptoKeyStore::Unlock(vMasterKey)) + { + int64 nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (pMasterKey.second.nDeriveIterations < 25000) + pMasterKey.second.nDeriveIterations = 25000; + + printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey)) + return false; + CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second); + if (fWasLocked) + Lock(); + return true; + } + } + } + return false; +} + + +// This class implements an addrIncoming entry that causes pre-0.4 +// clients to crash on startup if reading a private-key-encrypted wallet. +class CCorruptAddress +{ +public: + IMPLEMENT_SERIALIZE + ( + if (nType & SER_DISK) + READWRITE(nVersion); + ) +}; + +bool CWallet::EncryptWallet(const string& strWalletPassphrase) +{ + CRITICAL_BLOCK(cs_mapPubKeys) + CRITICAL_BLOCK(cs_KeyStore) + CRITICAL_BLOCK(cs_vMasterKey) + CRITICAL_BLOCK(cs_pwalletdbEncryption) + { + if (IsCrypted()) + return false; + + CKeyingMaterial vMasterKey; + RandAddSeedPerfmon(); + + vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); + RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); + + CMasterKey kMasterKey; + + RandAddSeedPerfmon(); + kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); + RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); + + CCrypter crypter; + int64 nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime)); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (kMasterKey.nDeriveIterations < 25000) + kMasterKey.nDeriveIterations = 25000; + + printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) + return false; + + mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; + if (fFileBacked) + { + pwalletdbEncryption = new CWalletDB(strWalletFile); + pwalletdbEncryption->TxnBegin(); + pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); + } + + if (!EncryptKeys(vMasterKey)) + { + if (fFileBacked) + pwalletdbEncryption->TxnAbort(); + exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet. + } + + if (fFileBacked) + { + CCorruptAddress corruptAddress; + pwalletdbEncryption->WriteSetting("addrIncoming", corruptAddress); + if (!pwalletdbEncryption->TxnCommit()) + exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet. + + pwalletdbEncryption->Close(); + pwalletdbEncryption = NULL; + } + + Lock(); + } + return true; } void CWallet::WalletUpdateSpent(const CTransaction &tx) @@ -98,7 +269,10 @@ BOOST_FOREACH(const CTxOut& txout, wtx.vout) { if (txout.scriptPubKey == scriptDefaultKey) - SetDefaultKey(GetKeyFromKeyPool()); + { + SetDefaultKey(GetOrReuseKeyFromPool()); + SetAddressBookName(PubKeyToAddress(vchDefaultKey), ""); + } } #endif // Notify UI @@ -552,8 +726,6 @@ int64 CWallet::GetBalance() const { - int64 nStart = GetTimeMillis(); - int64 nTotal = 0; CRITICAL_BLOCK(cs_mapWallet) { @@ -566,7 +738,6 @@ } } - //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart); return nTotal; } @@ -798,7 +969,7 @@ // Reserve a new key pair from key pool vector<unsigned char> vchPubKey = reservekey.GetReservedKey(); - assert(mapKeys.count(vchPubKey)); + // assert(mapKeys.count(vchPubKey)); // Fill a vout to ourself, using same address type as the payment CScript scriptChange; @@ -918,15 +1089,24 @@ { CReserveKey reservekey(this); int64 nFeeRequired; - if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) + CRITICAL_BLOCK(cs_vMasterKey) { - string strError; - if (nValue + nFeeRequired > GetBalance()) - strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str()); - else - strError = _("Error: Transaction creation failed "); - printf("SendMoney() : %s", strError.c_str()); - return strError; + if (IsLocked()) + { + string strError = _("Error: Wallet locked, unable to create transaction "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) + { + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str()); + else + strError = _("Error: Transaction creation failed "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } } if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) @@ -961,27 +1141,28 @@ -bool CWallet::LoadWallet(bool& fFirstRunRet) +int CWallet::LoadWallet(bool& fFirstRunRet) { if (!fFileBacked) return false; fFirstRunRet = false; - if (!CWalletDB(strWalletFile,"cr+").LoadWallet(this)) - return false; + int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this); + if (nLoadWalletRet != DB_LOAD_OK) + return nLoadWalletRet; fFirstRunRet = vchDefaultKey.empty(); - if (!mapKeys.count(vchDefaultKey)) + if (!HaveKey(vchDefaultKey)) { - // Create new default key + // Create new keyUser and set as default key RandAddSeedPerfmon(); - SetDefaultKey(GetKeyFromKeyPool()); + SetDefaultKey(GetOrReuseKeyFromPool()); if (!SetAddressBookName(PubKeyToAddress(vchDefaultKey), "")) - return false; + return DB_LOAD_FAIL; } CreateThread(ThreadFlushWalletDB, &strWalletFile); - return true; + return DB_LOAD_OK; } @@ -1048,14 +1229,16 @@ return true; } -void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) +bool CWallet::TopUpKeyPool() { - nIndex = -1; - keypool.vchPubKey.clear(); CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(cs_mapWallet) CRITICAL_BLOCK(cs_setKeyPool) + CRITICAL_BLOCK(cs_vMasterKey) { + if (IsLocked()) + return false; + CWalletDB walletdb(strWalletFile); // Top up key pool @@ -1066,18 +1249,36 @@ if (!setKeyPool.empty()) nEnd = *(--setKeyPool.end()) + 1; if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) - throw runtime_error("ReserveKeyFromKeyPool() : writing generated key failed"); + throw runtime_error("TopUpKeyPool() : writing generated key failed"); setKeyPool.insert(nEnd); printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size()); } + } + return true; +} + +void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) +{ + nIndex = -1; + keypool.vchPubKey.clear(); + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_setKeyPool) + { + if (!IsLocked()) + TopUpKeyPool(); // Get the oldest key - assert(!setKeyPool.empty()); + 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 (!mapKeys.count(keypool.vchPubKey)) + if (!HaveKey(keypool.vchPubKey)) throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); assert(!keypool.vchPubKey.empty()); printf("keypool reserve %"PRI64d"\n", nIndex); @@ -1106,11 +1307,13 @@ printf("keypool return %"PRI64d"\n", nIndex); } -vector<unsigned char> CWallet::GetKeyFromKeyPool() +vector<unsigned char> CWallet::GetOrReuseKeyFromPool() { int64 nIndex = 0; CKeyPool keypool; ReserveKeyFromKeyPool(nIndex, keypool); + if(nIndex == -1) + return vchDefaultKey; KeepKey(nIndex); return keypool.vchPubKey; } @@ -1120,6 +1323,8 @@ int64 nIndex = 0; CKeyPool keypool; ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) + return GetTime(); ReturnKey(nIndex); return keypool.nTime; } @@ -1130,7 +1335,13 @@ { CKeyPool keypool; pwallet->ReserveKeyFromKeyPool(nIndex, keypool); - vchPubKey = keypool.vchPubKey; + if (nIndex != -1) + vchPubKey = keypool.vchPubKey; + else + { + printf("CReserveKey::GetReservedKey(): Warning: using default key instead of a new key, top up your keypool."); + vchPubKey = pwallet->vchDefaultKey; + } } assert(!vchPubKey.empty()); return vchPubKey;
--- a/src/wallet.h +++ b/src/wallet.h @@ -12,12 +12,14 @@ class CReserveKey; class CWalletDB; -class CWallet : public CKeyStore +class CWallet : public CCryptoKeyStore { private: bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const; bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const; + CWalletDB *pwalletdbEncryption; + CCriticalSection cs_pwalletdbEncryption; public: bool fFileBacked; @@ -26,14 +28,22 @@ std::set<int64> setKeyPool; CCriticalSection cs_setKeyPool; + typedef std::map<unsigned int, CMasterKey> MasterKeyMap; + MasterKeyMap mapMasterKeys; + unsigned int nMasterKeyMaxID; + CWallet() { fFileBacked = false; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; } CWallet(std::string strWalletFileIn) { strWalletFile = strWalletFileIn; fFileBacked = true; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; } mutable CCriticalSection cs_mapWallet; @@ -48,7 +58,16 @@ std::vector<unsigned char> vchDefaultKey; + // keystore implementation bool AddKey(const CKey& key); + bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); } + bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); + bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } + + bool Unlock(const std::string& strWalletPassphrase); + bool ChangeWalletPassphrase(const std::string& strOldWalletPassphrase, const std::string& strNewWalletPassphrase); + bool EncryptWallet(const std::string& strWalletPassphrase); + bool AddToWallet(const CWalletTx& wtxIn); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false); bool EraseFromWallet(uint256 hash); @@ -65,10 +84,11 @@ std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); std::string SendMoneyToBitcoinAddress(std::string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + bool TopUpKeyPool(); void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); void KeepKey(int64 nIndex); void ReturnKey(int64 nIndex); - std::vector<unsigned char> GetKeyFromKeyPool(); + std::vector<unsigned char> GetOrReuseKeyFromPool(); int64 GetOldestKeyPoolTime(); bool IsMine(const CTxIn& txin) const; @@ -148,7 +168,7 @@ walletdb.WriteBestBlock(loc); } - bool LoadWallet(bool& fFirstRunRet); + int LoadWallet(bool& fFirstRunRet); // bool BackupWallet(const std::string& strDest); // requires cs_mapAddressBook lock @@ -175,6 +195,11 @@ } } + int GetKeyPoolSize() + { + return setKeyPool.size(); + } + bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); bool SetDefaultKey(const std::vector<unsigned char> &vchPubKey);