diff options
author | Jonas Schnelli <dev@jonasschnelli.ch> | 2016-09-16 16:45:36 +0200 |
---|---|---|
committer | John Newbery <john@johnnewbery.com> | 2019-01-30 16:26:52 -0500 |
commit | 49d2374acf5845c5f760b5fd241482f292164147 (patch) | |
tree | e063f45b28b8dfef299d92b11ed25fdc3ff43b73 | |
parent | a5daf70ffb80c14ddf9f35c638d9e8087d8732e9 (diff) |
[tools] Add wallet inspection and modification tool
This commit adds wallet-tool, a tool for creating and interacting with
wallet files. Original implementation was by Jonas Schnelli
<dev@jonasschnelli.ch> with modifications by John Newbery
<john@johnnewbery.com>
MSVC files were provided by Chun Kuan Lee <ken2812221@gmail.com>:
build: Add MSVC project files for bitcoin-wallet-tool
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | build_msvc/bitcoin-wallet/bitcoin-wallet.vcxproj | 195 | ||||
-rw-r--r-- | build_msvc/bitcoin.sln | 20 | ||||
-rw-r--r-- | build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in | 166 | ||||
-rw-r--r-- | build_msvc/msvc-autogen.py | 1 | ||||
-rw-r--r-- | configure.ac | 20 | ||||
-rw-r--r-- | src/Makefile.am | 40 | ||||
-rw-r--r-- | src/bitcoin-wallet-res.rc | 35 | ||||
-rw-r--r-- | src/bitcoin-wallet.cpp | 121 | ||||
-rw-r--r-- | src/wallet/crypter.cpp | 4 | ||||
-rw-r--r-- | src/wallet/crypter.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 4 | ||||
-rw-r--r-- | src/wallet/wallet.h | 2 | ||||
-rw-r--r-- | src/wallet/wallettool.cpp | 139 | ||||
-rw-r--r-- | src/wallet/wallettool.h | 20 |
15 files changed, 760 insertions, 10 deletions
diff --git a/.gitignore b/.gitignore index 380d2eab98..994d67402f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ src/bitcoin src/bitcoind src/bitcoin-cli src/bitcoin-tx +src/bitcoin-wallet src/test/test_bitcoin src/test/test_bitcoin_fuzzy src/qt/test/test_bitcoin-qt diff --git a/build_msvc/bitcoin-wallet/bitcoin-wallet.vcxproj b/build_msvc/bitcoin-wallet/bitcoin-wallet.vcxproj new file mode 100644 index 0000000000..b618aca817 --- /dev/null +++ b/build_msvc/bitcoin-wallet/bitcoin-wallet.vcxproj @@ -0,0 +1,195 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\bitcoin-wallet.cpp" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\libbitcoinconsensus\libbitcoinconsensus.vcxproj"> + <Project>{2b384fa8-9ee1-4544-93cb-0d733c25e8ce}</Project> + </ProjectReference> + <ProjectReference Include="..\libbitcoin_cli\libbitcoin_cli.vcxproj"> + <Project>{0667528c-d734-4009-adf9-c0d6c4a5a5a6}</Project> + </ProjectReference> + <ProjectReference Include="..\libbitcoin_common\libbitcoin_common.vcxproj"> + <Project>{7c87e378-df58-482e-aa2f-1bc129bc19ce}</Project> + </ProjectReference> + <ProjectReference Include="..\libbitcoin_crypto\libbitcoin_crypto.vcxproj"> + <Project>{6190199c-6cf4-4dad-bfbd-93fa72a760c1}</Project> + </ProjectReference> + <ProjectReference Include="..\libbitcoin_server\libbitcoin_server.vcxproj"> + <Project>{460fee33-1fe1-483f-b3bf-931ff8e969a5}</Project> + </ProjectReference> + <ProjectReference Include="..\libbitcoin_util\libbitcoin_util.vcxproj"> + <Project>{b53a5535-ee9d-4c6f-9a26-f79ee3bc3754}</Project> + </ProjectReference> + <ProjectReference Include="..\libbitcoin_wallet\libbitcoin_wallet.vcxproj"> + <Project>{93b86837-b543-48a5-a89b-7c87abb77df2}</Project> + </ProjectReference> + <ProjectReference Include="..\libbitcoin_zmq\libbitcoin_zmq.vcxproj"> + <Project>{792d487f-f14c-49fc-a9de-3fc150f31c3f}</Project> + </ProjectReference> + <ProjectReference Include="..\libunivalue\libunivalue.vcxproj"> + <Project>{5724ba7d-a09a-4ba8-800b-c4c1561b3d69}</Project> + </ProjectReference> + <ProjectReference Include="..\libbitcoin_wallet_tool\libbitcoin_wallet_tool.vcxproj"> + <Project>{f91ac55e-6f5e-4c58-9ac5-b40db7deef93}</Project> + </ProjectReference> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{84DE8790-EDE3-4483-81AC-C32F15E861F4}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>bitcointx</RootNamespace> + <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> + <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>crypt32.lib;Iphlpapi.lib;ws2_32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <Import Label="configTarget" Project="..\common.vcxproj" /> +</Project> diff --git a/build_msvc/bitcoin.sln b/build_msvc/bitcoin.sln index 32068d81f6..b84a525afa 100644 --- a/build_msvc/bitcoin.sln +++ b/build_msvc/bitcoin.sln @@ -32,6 +32,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_bitcoin", "bench_bitc EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitcoin-tx", "bitcoin-tx\bitcoin-tx.vcxproj", "{D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bitcoin-wallet", "bitcoin-wallet\bitcoin-wallet.vcxproj", "{84DE8790-EDE3-4483-81AC-C32F15E861F4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbitcoin_wallet_tool", "libbitcoin_wallet_tool\libbitcoin_wallet_tool.vcxproj", "{F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -160,6 +164,22 @@ Global {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x64.Build.0 = Release|x64 {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x86.ActiveCfg = Release|Win32 {D3022AF6-AD33-4CE3-B358-87CB6A1B29CF}.Release|x86.Build.0 = Release|Win32 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Debug|x64.ActiveCfg = Debug|x64 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Debug|x64.Build.0 = Debug|x64 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Debug|x86.ActiveCfg = Debug|Win32 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Debug|x86.Build.0 = Debug|Win32 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Release|x64.ActiveCfg = Release|x64 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Release|x64.Build.0 = Release|x64 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Release|x86.ActiveCfg = Release|Win32 + {84DE8790-EDE3-4483-81AC-C32F15E861F4}.Release|x86.Build.0 = Release|Win32 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Debug|x64.ActiveCfg = Debug|x64 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Debug|x64.Build.0 = Debug|x64 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Debug|x86.ActiveCfg = Debug|Win32 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Debug|x86.Build.0 = Debug|Win32 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Release|x64.ActiveCfg = Release|x64 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Release|x64.Build.0 = Release|x64 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Release|x86.ActiveCfg = Release|Win32 + {F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in b/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in new file mode 100644 index 0000000000..b9cf68aee0 --- /dev/null +++ b/build_msvc/libbitcoin_wallet_tool/libbitcoin_wallet_tool.vcxproj.in @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Label="configInitTarget" Project="..\common.init.vcxproj" /> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> +@SOURCE_FILES@ + </ItemGroup> + <ItemGroup> + <None Include="packages.config" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{F91AC55E-6F5E-4C58-9AC5-B40DB7DEEF93}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>libbitcoin_zmq</RootNamespace> + <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet> + <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v141</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <SuppressStartupBanner>false</SuppressStartupBanner> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <SuppressStartupBanner>false</SuppressStartupBanner> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <SuppressStartupBanner>false</SuppressStartupBanner> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NOMINMAX;ZMQ_STATIC;HAVE_CONFIG_H;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>..\..\src;..\..\src\univalue\include;</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <SuppressStartupBanner>false</SuppressStartupBanner> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <Import Label="configTarget" Project="..\common.vcxproj" /> +</Project> diff --git a/build_msvc/msvc-autogen.py b/build_msvc/msvc-autogen.py index f351532f9d..c8df29eecb 100644 --- a/build_msvc/msvc-autogen.py +++ b/build_msvc/msvc-autogen.py @@ -11,6 +11,7 @@ libs = [ 'libbitcoin_crypto', 'libbitcoin_server', 'libbitcoin_util', + 'libbitcoin_wallet_tool', 'libbitcoin_wallet', 'libbitcoin_zmq', ] diff --git a/configure.ac b/configure.ac index e1c265f10f..190288f5f8 100644 --- a/configure.ac +++ b/configure.ac @@ -19,6 +19,7 @@ BITCOIN_DAEMON_NAME=bitcoind BITCOIN_GUI_NAME=bitcoin-qt BITCOIN_CLI_NAME=bitcoin-cli BITCOIN_TX_NAME=bitcoin-tx +BITCOIN_WALLET_TOOL_NAME=bitcoin-wallet dnl Unless the user specified ARFLAGS, force it to be cr AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to <cr> if not set]) @@ -415,7 +416,7 @@ CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" AC_ARG_WITH([utils], [AS_HELP_STRING([--with-utils], - [build bitcoin-cli bitcoin-tx (default=yes)])], + [build bitcoin-cli bitcoin-tx bitcoin-wallet (default=yes)])], [build_bitcoin_utils=$withval], [build_bitcoin_utils=yes]) @@ -431,6 +432,12 @@ AC_ARG_ENABLE([util-tx], [build_bitcoin_tx=$enableval], [build_bitcoin_tx=$build_bitcoin_utils]) +AC_ARG_ENABLE([util-wallet], + [AS_HELP_STRING([--enable-util-wallet], + [build bitcoin-wallet])], + [build_bitcoin_wallet=$enableval], + [build_bitcoin_wallet=$build_bitcoin_utils]) + AC_ARG_WITH([libs], [AS_HELP_STRING([--with-libs], [build libraries (default=yes)])], @@ -911,7 +918,7 @@ BITCOIN_QT_INIT dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus BITCOIN_QT_CONFIGURE([$use_pkgconfig]) -if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnononononono; then +if test x$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononononono; then use_boost=no else use_boost=yes @@ -1193,7 +1200,7 @@ dnl univalue check need_bundled_univalue=yes -if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnononononono; then +if test x$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononononono; then need_bundled_univalue=no else @@ -1255,6 +1262,10 @@ AC_MSG_CHECKING([whether to build bitcoin-tx]) AM_CONDITIONAL([BUILD_BITCOIN_TX], [test x$build_bitcoin_tx = xyes]) AC_MSG_RESULT($build_bitcoin_tx) +AC_MSG_CHECKING([whether to build bitcoin-wallet]) +AM_CONDITIONAL([BUILD_BITCOIN_WALLET], [test x$build_bitcoin_wallet = xyes]) +AC_MSG_RESULT($build_bitcoin_wallet) + AC_MSG_CHECKING([whether to build libraries]) AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes]) if test x$build_bitcoin_libs = xyes; then @@ -1396,7 +1407,7 @@ else AC_MSG_RESULT([no]) fi -if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnonononononono; then +if test x$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnononononononono; then AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests]) fi @@ -1442,6 +1453,7 @@ AC_SUBST(BITCOIN_DAEMON_NAME) AC_SUBST(BITCOIN_GUI_NAME) AC_SUBST(BITCOIN_CLI_NAME) AC_SUBST(BITCOIN_TX_NAME) +AC_SUBST(BITCOIN_WALLET_TOOL_NAME) AC_SUBST(RELDFLAGS) AC_SUBST(DEBUG_CPPFLAGS) diff --git a/src/Makefile.am b/src/Makefile.am index 09daaebd23..b710bf7f68 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,6 +41,7 @@ LIBBITCOINCONSENSUS=libbitcoinconsensus.la endif if ENABLE_WALLET LIBBITCOIN_WALLET=libbitcoin_wallet.a +LIBBITCOIN_WALLET_TOOL=libbitcoin_wallet_tool.a endif LIBBITCOIN_CRYPTO= $(LIBBITCOIN_CRYPTO_BASE) @@ -70,6 +71,7 @@ EXTRA_LIBRARIES += \ $(LIBBITCOIN_SERVER) \ $(LIBBITCOIN_CLI) \ $(LIBBITCOIN_WALLET) \ + $(LIBBITCOIN_WALLET_TOOL) \ $(LIBBITCOIN_ZMQ) lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS) @@ -89,6 +91,11 @@ endif if BUILD_BITCOIN_TX bin_PROGRAMS += bitcoin-tx endif +if ENABLE_WALLET +if BUILD_BITCOIN_WALLET + bin_PROGRAMS += bitcoin-wallet +endif +endif .PHONY: FORCE check-symbols check-security # bitcoin core # @@ -203,6 +210,7 @@ BITCOIN_CORE_H = \ wallet/rpcwallet.h \ wallet/wallet.h \ wallet/walletdb.h \ + wallet/wallettool.h \ wallet/walletutil.h \ wallet/coinselection.h \ warnings.h \ @@ -305,6 +313,12 @@ libbitcoin_wallet_a_SOURCES = \ wallet/coinselection.cpp \ $(BITCOIN_CORE_H) +libbitcoin_wallet_tool_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_wallet_tool_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_wallet_tool_a_SOURCES = \ + wallet/wallettool.cpp \ + $(BITCOIN_CORE_H) + # crypto primitives library crypto_libbitcoin_crypto_base_a_CPPFLAGS = $(AM_CPPFLAGS) crypto_libbitcoin_crypto_base_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) @@ -522,6 +536,32 @@ bitcoin_tx_LDADD = \ bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) # +# bitcoin-wallet binary # +bitcoin_wallet_SOURCES = bitcoin-wallet.cpp +bitcoin_wallet_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +bitcoin_wallet_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +bitcoin_wallet_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +if TARGET_WINDOWS +bitcoin_wallet_SOURCES += bitcoin-wallet-res.rc +endif + +bitcoin_wallet_LDADD = \ + $(LIBBITCOIN_WALLET_TOOL) \ + $(LIBBITCOIN_WALLET) \ + $(LIBBITCOIN_SERVER) \ + $(LIBBITCOIN_COMMON) \ + $(LIBBITCOIN_CONSENSUS) \ + $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBLEVELDB) \ + $(LIBLEVELDB_SSE42) \ + $(LIBMEMENV) \ + $(LIBSECP256K1) + +bitcoin_wallet_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) +# + # bitcoinconsensus library # if BUILD_BITCOIN_LIBS include_HEADERS = script/bitcoinconsensus.h diff --git a/src/bitcoin-wallet-res.rc b/src/bitcoin-wallet-res.rc new file mode 100644 index 0000000000..e9fa2dbb40 --- /dev/null +++ b/src/bitcoin-wallet-res.rc @@ -0,0 +1,35 @@ +#include <windows.h> // needed for VERSIONINFO +#include "clientversion.h" // holds the needed client version information + +#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD +#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD) +#define VER_FILEVERSION VER_PRODUCTVERSION +#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // U.S. English - multilingual (hex) + BEGIN + VALUE "CompanyName", "Bitcoin" + VALUE "FileDescription", "bitcoin-wallet (CLI tool for " PACKAGE_NAME " wallets)" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "bitcoin-wallet" + VALUE "LegalCopyright", COPYRIGHT_STR + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "OriginalFilename", "bitcoin-wallet.exe" + VALUE "ProductName", "bitcoin-wallet" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) + END +END diff --git a/src/bitcoin-wallet.cpp b/src/bitcoin-wallet.cpp new file mode 100644 index 0000000000..293e3efa5c --- /dev/null +++ b/src/bitcoin-wallet.cpp @@ -0,0 +1,121 @@ +// Copyright (c) 2016-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#if defined(HAVE_CONFIG_H) +#include <config/bitcoin-config.h> +#endif + +#include <chainparams.h> +#include <chainparamsbase.h> +#include <consensus/consensus.h> +#include <logging.h> +#include <util/system.h> +#include <util/strencodings.h> +#include <wallet/wallettool.h> + +#include <stdio.h> + +const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr; + +static void SetupWalletToolArgs() +{ + SetupChainParamsBaseOptions(); + + gArgs.AddArg("-?", "This help message", false, OptionsCategory::OPTIONS); + gArgs.AddArg("-datadir=<dir>", "Specify data directory", false, OptionsCategory::OPTIONS); + gArgs.AddArg("-wallet=<wallet-name>", "Specify wallet name", false, OptionsCategory::OPTIONS); + gArgs.AddArg("-debug=<category>", "Output debugging information (default: 0).", false, OptionsCategory::DEBUG_TEST); + gArgs.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -debug is true, 0 otherwise.", false, OptionsCategory::DEBUG_TEST); + + gArgs.AddArg("info", "Get wallet info", false, OptionsCategory::COMMANDS); + gArgs.AddArg("create", "Create new wallet file", false, OptionsCategory::COMMANDS); + + // Hidden + gArgs.AddArg("-h", "", false, OptionsCategory::HIDDEN); + gArgs.AddArg("-help", "", false, OptionsCategory::HIDDEN); +} + +static bool WalletAppInit(int argc, char* argv[]) +{ + SetupWalletToolArgs(); + std::string error_message; + if (!gArgs.ParseParameters(argc, argv, error_message)) { + fprintf(stderr, "Error parsing command line arguments: %s\n", error_message.c_str()); + return false; + } + if (argc < 2 || HelpRequested(gArgs)) { + std::string usage = strprintf("%s bitcoin-wallet version", PACKAGE_NAME) + " " + FormatFullVersion() + "\n\n" + + "wallet-tool is an offline tool for creating and interacting with Bitcoin Core wallet files.\n" + + "By default wallet-tool will act on wallets in the default mainnet wallet directory in the datadir.\n" + + "To change the target wallet, use the -datadir, -wallet and -testnet/-regtest arguments.\n\n" + + "Usage:\n" + + " bitcoin-wallet [options] <command>\n\n" + + gArgs.GetHelpMessage(); + + fprintf(stdout, "%s", usage.c_str()); + return false; + } + + // check for printtoconsole, allow -debug + g_logger->m_print_to_console = gArgs.GetBoolArg("-printtoconsole", gArgs.GetBoolArg("-debug", false)); + + if (!fs::is_directory(GetDataDir(false))) { + fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); + return false; + } + // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) + SelectParams(gArgs.GetChainName()); + + return true; +} + +int main(int argc, char* argv[]) +{ +#ifdef WIN32 + util::WinCmdLineArgs winArgs; + std::tie(argc, argv) = winArgs.get(); +#endif + SetupEnvironment(); + RandomInit(); + try { + if (!WalletAppInit(argc, argv)) return EXIT_FAILURE; + } catch (const std::exception& e) { + PrintExceptionContinue(&e, "WalletAppInit()"); + return EXIT_FAILURE; + } catch (...) { + PrintExceptionContinue(nullptr, "WalletAppInit()"); + return EXIT_FAILURE; + } + + std::string method {}; + for(int i = 1; i < argc; ++i) { + if (!IsSwitchChar(argv[i][0])) { + if (!method.empty()) { + fprintf(stderr, "Error: two methods provided (%s and %s). Only one method should be provided.\n", method.c_str(), argv[i]); + return EXIT_FAILURE; + } + method = argv[i]; + } + } + + if (method.empty()) { + fprintf(stderr, "No method provided. Run `bitcoin-wallet -help` for valid methods.\n"); + return EXIT_FAILURE; + } + + // A name must be provided when creating a file + if (method == "create" && !gArgs.IsArgSet("-wallet")) { + fprintf(stderr, "Wallet name must be provided when creating a new wallet.\n"); + return EXIT_FAILURE; + } + + std::string name = gArgs.GetArg("-wallet", ""); + + ECCVerifyHandle globalVerifyHandle; + ECC_Start(); + if (!WalletTool::ExecuteWalletToolFunc(method, name)) + return EXIT_FAILURE; + ECC_Stop(); + return EXIT_SUCCESS; +} diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index f5ac6e98b2..1dc78255f6 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -175,7 +175,7 @@ bool CCryptoKeyStore::Lock() return true; } -bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) +bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys) { { LOCK(cs_KeyStore); @@ -204,7 +204,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n"); throw std::runtime_error("Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt."); } - if (keyFail || !keyPass) + if (keyFail || (!keyPass && !accept_no_keys)) return false; vMasterKey = vMasterKeyIn; fDecryptionThoroughlyChecked = true; diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 418316c398..8e195ca8fa 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -133,7 +133,7 @@ protected: //! will encrypt previously unencrypted keys bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); - bool Unlock(const CKeyingMaterial& vMasterKeyIn); + bool Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys = false); CryptedKeyMap mapCryptedKeys GUARDED_BY(cs_KeyStore); public: diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 098055673b..154ae2d51f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -398,7 +398,7 @@ bool CWallet::LoadWatchOnly(const CScript &dest) return CCryptoKeyStore::AddWatchOnly(dest); } -bool CWallet::Unlock(const SecureString& strWalletPassphrase) +bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys) { CCrypter crypter; CKeyingMaterial _vMasterKey; @@ -411,7 +411,7 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase) return false; if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey)) continue; // try another master key - if (CCryptoKeyStore::Unlock(_vMasterKey)) + if (CCryptoKeyStore::Unlock(_vMasterKey, accept_no_keys)) return true; } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6872fbad2d..0f7c7bdfe7 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -887,7 +887,7 @@ public: //! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock(). int64_t nRelockTime = 0; - bool Unlock(const SecureString& strWalletPassphrase); + bool Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys = false); bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); bool EncryptWallet(const SecureString& strWalletPassphrase); diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp new file mode 100644 index 0000000000..30b0c48eef --- /dev/null +++ b/src/wallet/wallettool.cpp @@ -0,0 +1,139 @@ +// Copyright (c) 2016-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <base58.h> +#include <fs.h> +#include <interfaces/chain.h> +#include <util/system.h> +#include <wallet/wallet.h> +#include <wallet/walletutil.h> + +namespace WalletTool { + +// The standard wallet deleter function blocks on the validation interface +// queue, which doesn't exist for the bitcoin-wallet. Define our own +// deleter here. +static void WalletToolReleaseWallet(CWallet* wallet) +{ + wallet->WalletLogPrintf("Releasing wallet\n"); + wallet->Flush(); + delete wallet; +} + +static std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs::path& path) +{ + if (fs::exists(path)) { + fprintf(stderr, "Error: File exists already\n"); + return nullptr; + } + // dummy chain interface + auto chain = interfaces::MakeChain(); + std::shared_ptr<CWallet> wallet_instance(new CWallet(*chain, WalletLocation(name), WalletDatabase::Create(path)), WalletToolReleaseWallet); + bool first_run = true; + DBErrors load_wallet_ret = wallet_instance->LoadWallet(first_run); + if (load_wallet_ret != DBErrors::LOAD_OK) { + fprintf(stderr, "Error creating %s", name.c_str()); + return nullptr; + } + + wallet_instance->SetMinVersion(FEATURE_HD_SPLIT); + + // generate a new HD seed + CPubKey seed = wallet_instance->GenerateNewSeed(); + wallet_instance->SetHDSeed(seed); + + fprintf(stdout, "Topping up keypool...\n"); + wallet_instance->TopUpKeyPool(); + return wallet_instance; +} + +static std::shared_ptr<CWallet> LoadWallet(const std::string& name, const fs::path& path) +{ + if (!fs::exists(path)) { + fprintf(stderr, "Error: Wallet files does not exist\n"); + return nullptr; + } + + // dummy chain interface + auto chain = interfaces::MakeChain(); + std::shared_ptr<CWallet> wallet_instance(new CWallet(*chain, WalletLocation(name), WalletDatabase::Create(path)), WalletToolReleaseWallet); + DBErrors load_wallet_ret; + try { + bool first_run; + load_wallet_ret = wallet_instance->LoadWallet(first_run); + } catch (const std::runtime_error) { + fprintf(stderr, "Error loading %s. Is wallet being used by another process?\n", name.c_str()); + return nullptr; + } + + if (load_wallet_ret != DBErrors::LOAD_OK) { + wallet_instance = nullptr; + if (load_wallet_ret == DBErrors::CORRUPT) { + fprintf(stderr, "Error loading %s: Wallet corrupted", name.c_str()); + return nullptr; + } else if (load_wallet_ret == DBErrors::NONCRITICAL_ERROR) { + fprintf(stderr, "Error reading %s! All keys read correctly, but transaction data" + " or address book entries might be missing or incorrect.", + name.c_str()); + } else if (load_wallet_ret == DBErrors::TOO_NEW) { + fprintf(stderr, "Error loading %s: Wallet requires newer version of %s", + name.c_str(), PACKAGE_NAME); + return nullptr; + } else if (load_wallet_ret == DBErrors::NEED_REWRITE) { + fprintf(stderr, "Wallet needed to be rewritten: restart %s to complete", PACKAGE_NAME); + return nullptr; + } else { + fprintf(stderr, "Error loading %s", name.c_str()); + return nullptr; + } + } + + return wallet_instance; +} + +static void WalletShowInfo(CWallet* wallet_instance) +{ + // lock required because of some AssertLockHeld() + LOCK(wallet_instance->cs_wallet); + + fprintf(stdout, "Wallet info\n===========\n"); + fprintf(stdout, "Encrypted: %s\n", wallet_instance->IsCrypted() ? "yes" : "no"); + fprintf(stdout, "HD (hd seed available): %s\n", wallet_instance->GetHDChain().seed_id.IsNull() ? "no" : "yes"); + fprintf(stdout, "Keypool Size: %u\n", wallet_instance->GetKeyPoolSize()); + fprintf(stdout, "Transactions: %zu\n", wallet_instance->mapWallet.size()); + fprintf(stdout, "Address Book: %zu\n", wallet_instance->mapAddressBook.size()); +} + +bool ExecuteWalletToolFunc(const std::string& command, const std::string& name) +{ + fs::path path = fs::absolute(name, GetWalletDir()); + + if (command == "create") { + std::shared_ptr<CWallet> wallet_instance = CreateWallet(name, path); + if (wallet_instance) { + WalletShowInfo(wallet_instance.get()); + wallet_instance->Flush(); + } + } else if (command == "info") { + if (!fs::exists(path)) { + fprintf(stderr, "Error: no wallet file at %s\n", name.c_str()); + return false; + } + std::string error; + if (!WalletBatch::VerifyEnvironment(path, error)) { + fprintf(stderr, "Error loading %s. Is wallet being used by other process?\n", name.c_str()); + return false; + } + std::shared_ptr<CWallet> wallet_instance = LoadWallet(name, path); + if (!wallet_instance) return false; + WalletShowInfo(wallet_instance.get()); + wallet_instance->Flush(); + } else { + fprintf(stderr, "Invalid command: %s\n", command.c_str()); + return false; + } + + return true; +} +} // namespace WalletTool diff --git a/src/wallet/wallettool.h b/src/wallet/wallettool.h new file mode 100644 index 0000000000..5b06fd1792 --- /dev/null +++ b/src/wallet/wallettool.h @@ -0,0 +1,20 @@ +// Copyright (c) 2016-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_WALLET_WALLETTOOL_H +#define BITCOIN_WALLET_WALLETTOOL_H + +#include <script/ismine.h> +#include <wallet/wallet.h> + +namespace WalletTool { + +std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs::path& path); +std::shared_ptr<CWallet> LoadWallet(const std::string& name, const fs::path& path); +void WalletShowInfo(CWallet* wallet_instance); +bool ExecuteWalletToolFunc(const std::string& command, const std::string& file); + +} // namespace WalletTool + +#endif // BITCOIN_WALLET_WALLETTOOL_H |