diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..538773f --- /dev/null +++ b/.gitignore @@ -0,0 +1,305 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/a +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +package-lock.json +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# Visual Studio Code +.vscode + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc +*.DS_Store + +.vs/ +slnx.sqlite + +# Generated Protobuf classes +*.g.cs +*.c.cs +grpc_csharp_plugin +*Grpc.cs +**/Generated/*.cs + +launchSettings.json + +yarn.lock + +results/coverage.json +results/coverage.opencover.xml + +aelf.js + +**/contract_csharp_plugin +**/contract_csharp_plugin.exe + +**/BenchmarkDotNet.Artifacts/* + +*.zip + +**/package-lock.json + +Contracts.manifest + +# Contract patcher dlls +chain/scripts/patcher/* + +.dotnet +.store +tools/dotnet-cake +*.dll +*.dll.patched diff --git a/AElf.KeyStore.sln b/AElf.KeyStore.sln new file mode 100644 index 0000000..5288818 --- /dev/null +++ b/AElf.KeyStore.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.KeyStore", "src\AElf.KeyStore.csproj", "{73822C38-64B4-4B3A-8667-62D1888DA04B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.KeyStore.Tests", "test\AElf.KeyStore.Tests.csproj", "{7529B60F-E876-45D7-A531-0409486ED5AC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {73822C38-64B4-4B3A-8667-62D1888DA04B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {73822C38-64B4-4B3A-8667-62D1888DA04B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {73822C38-64B4-4B3A-8667-62D1888DA04B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {73822C38-64B4-4B3A-8667-62D1888DA04B}.Release|Any CPU.Build.0 = Release|Any CPU + {7529B60F-E876-45D7-A531-0409486ED5AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7529B60F-E876-45D7-A531-0409486ED5AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7529B60F-E876-45D7-A531-0409486ED5AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7529B60F-E876-45D7-A531-0409486ED5AC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/CodeCoverage.runsettings b/CodeCoverage.runsettings new file mode 100644 index 0000000..790dcc0 --- /dev/null +++ b/CodeCoverage.runsettings @@ -0,0 +1,17 @@ + + + + + + + + cobertura + [xunit.*]*,[*Tests]* + **/test/**/*.cs + Obsolete,GeneratedCodeAttribute + false + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 51c2781..f6248d5 100644 --- a/README.md +++ b/README.md @@ -1 +1,18 @@ -# aelf-keystore \ No newline at end of file +# aelf-keystore +======= + +# AElf.KeyStore + +## Introduction + +This project is designed for the mutual conversion of privateKey and keyStore. The tool references two libraries, +AElf.Cryptography and Nethereum.KeyStore, +to implement these functions. The project will be packaged into a NuGet package for use by other projects. + +## Usage + +- To reference in a C# project: + +``` + +``` \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..338ee47 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,34 @@ +jobs: + # All tasks on Linux + - job: build_all_linux + displayName: Build all tasks (Linux) + timeoutInMinutes: 120 + pool: + vmImage: ubuntu-latest + variables: + CI_TEST: true + steps: + - task: RunLinter@0 + displayName: RunLinter + - script: bash check.sh + displayName: 'Run Linter' + - task: UseDotNet@2 + displayName: 'Install .NET Core SDK' + inputs: + version: 7.0.x + - script: bash build.sh --target=Test-with-Codecov + displayName: 'Build and Test' + - task: PublishTestResults@2 + condition: always() + inputs: + testRunner: VSTest + testResultsFiles: '**/*.trx' + - task: reportgenerator@5 + displayName: ReportGenerator + inputs: + reports: '$(Build.SourcesDirectory)/test/TestResults/*/coverage.cobertura.xml' + targetdir: '$(Build.SourcesDirectory)/CodeCoverage' + reporttypes: 'Cobertura' + assemblyfilters: '-xunit*' + - script: bash build.sh --target=Upload-Coverage-Azure + displayName: 'Upload data to Codecov' diff --git a/build.cake b/build.cake new file mode 100644 index 0000000..dfb7526 --- /dev/null +++ b/build.cake @@ -0,0 +1,78 @@ +#tool nuget:?package=Codecov +#addin nuget:?package=Cake.Codecov&version=0.8.0 + +var target = Argument("target", "Default"); +var configuration = Argument("configuration", "Debug"); +var rootPath = "./"; +var srcPath = rootPath + "src/"; +var testPath = rootPath + "test/"; +var solution = rootPath + "AElf.KeyStore.sln"; + +Task("Clean") + .Description("clean up project cache") + .Does(() => +{ + CleanDirectories(srcPath + "**/bin"); + CleanDirectories(srcPath + "**/obj"); + CleanDirectories(testPath + "**/bin"); + CleanDirectories(testPath + "**/obj"); +}); + +Task("Restore") + .Description("restore project dependencies") + .Does(() => +{ + DotNetCoreRestore(solution, new DotNetCoreRestoreSettings + { + Verbosity = DotNetCoreVerbosity.Quiet, + Sources = new [] { "https://www.myget.org/F/aelf-project-dev/api/v3/index.json", "https://api.nuget.org/v3/index.json" } + }); +}); +Task("Build") + .Description("Compilation project") + .IsDependentOn("Clean") + .IsDependentOn("Restore") + .Does(() => +{ + var buildSetting = new DotNetCoreBuildSettings{ + NoRestore = true, + Configuration = configuration, + ArgumentCustomization = args => { + return args.Append("/clp:ErrorsOnly") + .Append("-v quiet");} + }; + + DotNetCoreBuild(solution, buildSetting); +}); + +Task("Test-with-Codecov") + .Description("operation tes") + .IsDependentOn("Build") + .Does(() => +{ + var testSetting = new DotNetCoreTestSettings{ + Configuration = configuration, + NoRestore = true, + NoBuild = true, + ArgumentCustomization = args => { + return args + .Append("--logger trx") + .Append("--settings CodeCoverage.runsettings") + .Append("--collect:\"XPlat Code Coverage\""); + } + }; + var testProjects = GetFiles("./test/*.csproj"); + var testProjectList = testProjects.OrderBy(p=>p.FullPath).ToList(); + foreach(var testProject in testProjectList) + { + DotNetCoreTest(testProject.FullPath, testSetting); + } +}); + +Task("Upload-Coverage-Azure") + .Does(() => +{ + Codecov("./CodeCoverage/Cobertura.xml",EnvironmentVariable("CODECOV_TOKEN")); +}); + +RunTarget(target); diff --git a/build.config b/build.config new file mode 100644 index 0000000..a19aea9 --- /dev/null +++ b/build.config @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + CAKE_VERSION=0.37.0 + DOTNET_VERSION=7.0.100 \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..e48d09a --- /dev/null +++ b/build.ps1 @@ -0,0 +1,154 @@ +#!/usr/bin/env pwsh +$DotNetInstallerUri = 'https://dot.net/v1/dotnet-install.ps1'; +$DotNetUnixInstallerUri = 'https://dot.net/v1/dotnet-install.sh' +$DotNetChannel = 'LTS' +$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent + +[string] $CakeVersion = '' +[string] $DotNetVersion= '' +foreach($line in Get-Content (Join-Path $PSScriptRoot 'build.config')) +{ + if ($line -like 'CAKE_VERSION=*') { + $CakeVersion = $line.SubString(13) + } + elseif ($line -like 'DOTNET_VERSION=*') { + $DotNetVersion =$line.SubString(15) + } +} + + +if ([string]::IsNullOrEmpty($CakeVersion) -or [string]::IsNullOrEmpty($DotNetVersion)) { + 'Failed to parse Cake / .NET Core SDK Version' + exit 1 +} + +# Make sure tools folder exists +$ToolPath = Join-Path $PSScriptRoot "tools" +if (!(Test-Path $ToolPath)) { + Write-Verbose "Creating tools directory..." + New-Item -Path $ToolPath -Type Directory -Force | out-null +} + + +if ($PSVersionTable.PSEdition -ne 'Core') { + # Attempt to set highest encryption available for SecurityProtocol. + # PowerShell will not set this by default (until maybe .NET 4.6.x). This + # will typically produce a message for PowerShell v2 (just an info + # message though) + try { + # Set TLS 1.2 (3072), then TLS 1.1 (768), then TLS 1.0 (192), finally SSL 3.0 (48) + # Use integers because the enumeration values for TLS 1.2 and TLS 1.1 won't + # exist in .NET 4.0, even though they are addressable if .NET 4.5+ is + # installed (.NET 4.5 is an in-place upgrade). + [System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192 -bor 48 + } catch { + Write-Output 'Unable to set PowerShell to use TLS 1.2 and TLS 1.1 due to old .NET Framework installed. If you see underlying connection closed or trust errors, you may need to upgrade to .NET Framework 4.5+ and PowerShell v3' + } +} + +########################################################################### +# INSTALL .NET CORE CLI +########################################################################### + +$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +$env:DOTNET_CLI_TELEMETRY_OPTOUT=1 +$env:DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX=2 + + +Function Remove-PathVariable([string]$VariableToRemove) +{ + $SplitChar = ';' + if ($IsMacOS -or $IsLinux) { + $SplitChar = ':' + } + + $path = [Environment]::GetEnvironmentVariable("PATH", "User") + if ($path -ne $null) + { + $newItems = $path.Split($SplitChar, [StringSplitOptions]::RemoveEmptyEntries) | Where-Object { "$($_)" -inotlike $VariableToRemove } + [Environment]::SetEnvironmentVariable("PATH", [System.String]::Join($SplitChar, $newItems), "User") + } + + $path = [Environment]::GetEnvironmentVariable("PATH", "Process") + if ($path -ne $null) + { + $newItems = $path.Split($SplitChar, [StringSplitOptions]::RemoveEmptyEntries) | Where-Object { "$($_)" -inotlike $VariableToRemove } + [Environment]::SetEnvironmentVariable("PATH", [System.String]::Join($SplitChar, $newItems), "Process") + } +} + +# Get .NET Core CLI path if installed. +$FoundDotNetCliVersion = $null; +if (Get-Command dotnet -ErrorAction SilentlyContinue) { + $FoundDotNetCliVersion = dotnet --version; +} + +if($FoundDotNetCliVersion -ne $DotNetVersion) { + $InstallPath = Join-Path $PSScriptRoot ".dotnet" + if (!(Test-Path $InstallPath)) { + New-Item -Path $InstallPath -ItemType Directory -Force | Out-Null; + } + + if ($IsMacOS -or $IsLinux) { + $ScriptPath = Join-Path $InstallPath 'dotnet-install.sh' + (New-Object System.Net.WebClient).DownloadFile($DotNetUnixInstallerUri, $ScriptPath); + & bash $ScriptPath --version "$DotNetVersion" --install-dir "$InstallPath" --channel "$DotNetChannel" --no-path + + Remove-PathVariable "$InstallPath" + $env:PATH = "$($InstallPath):$env:PATH" + } + else { + $ScriptPath = Join-Path $InstallPath 'dotnet-install.ps1' + (New-Object System.Net.WebClient).DownloadFile($DotNetInstallerUri, $ScriptPath); + & $ScriptPath -Channel $DotNetChannel -Version $DotNetVersion -InstallDir $InstallPath; + + Remove-PathVariable "$InstallPath" + $env:PATH = "$InstallPath;$env:PATH" + } + $env:DOTNET_ROOT=$InstallPath +} + +########################################################################### +# INSTALL CAKE +########################################################################### + +# Make sure Cake has been installed. +[string] $CakeExePath = '' +[string] $CakeInstalledVersion = Get-Command dotnet-cake -ErrorAction SilentlyContinue | % {&$_.Source --version} + +if ($CakeInstalledVersion -eq $CakeVersion) { + # Cake found locally + $CakeExePath = (Get-Command dotnet-cake).Source +} +else { + $CakePath = [System.IO.Path]::Combine($ToolPath,'.store', 'cake.tool', $CakeVersion) # Old PowerShell versions Join-Path only supports one child path + + $CakeExePath = (Get-ChildItem -Path $ToolPath -Filter "dotnet-cake*" -File| ForEach-Object FullName | Select-Object -First 1) + + + if ((!(Test-Path -Path $CakePath -PathType Container)) -or (!(Test-Path $CakeExePath -PathType Leaf))) { + + if ((![string]::IsNullOrEmpty($CakeExePath)) -and (Test-Path $CakeExePath -PathType Leaf)) + { + & dotnet tool uninstall --tool-path $ToolPath Cake.Tool + } + + & dotnet tool install --tool-path $ToolPath --version $CakeVersion Cake.Tool + if ($LASTEXITCODE -ne 0) + { + 'Failed to install cake' + exit 1 + } + $CakeExePath = (Get-ChildItem -Path $ToolPath -Filter "dotnet-cake*" -File| ForEach-Object FullName | Select-Object -First 1) + } +} + +########################################################################### +# RUN BUILD SCRIPT +########################################################################### +& "$CakeExePath" ./build.cake --bootstrap +if ($LASTEXITCODE -eq 0) +{ + & "$CakeExePath" ./build.cake $args +} +exit $LASTEXITCODE \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..06bcee8 --- /dev/null +++ b/build.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +# Define varibles +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +source $SCRIPT_DIR/build.config +TOOLS_DIR=$SCRIPT_DIR/tools +CAKE_EXE=$TOOLS_DIR/dotnet-cake +CAKE_PATH=$TOOLS_DIR/.store/cake.tool/$CAKE_VERSION + +if [ "$CAKE_VERSION" = "" ] || [ "$DOTNET_VERSION" = "" ]; then + echo "An error occured while parsing Cake / .NET Core SDK version." + exit 1 +fi + +# Make sure the tools folder exist. +if [ ! -d "$TOOLS_DIR" ]; then + mkdir "$TOOLS_DIR" +fi + +########################################################################### +# INSTALL .NET CORE CLI +########################################################################### + +export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=0 +export DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX=2 + +DOTNET_INSTALLED_VERSION=$(dotnet --version 2>&1) + +if [ "$DOTNET_VERSION" != "$DOTNET_INSTALLED_VERSION" ]; then + echo "Installing .NET CLI..." + if [ ! -d "$SCRIPT_DIR/.dotnet" ]; then + mkdir "$SCRIPT_DIR/.dotnet" + fi + curl -Lsfo "$SCRIPT_DIR/.dotnet/dotnet-install.sh" https://dot.net/v1/dotnet-install.sh + bash "$SCRIPT_DIR/.dotnet/dotnet-install.sh" --version $DOTNET_VERSION --install-dir .dotnet --no-path + export PATH="$SCRIPT_DIR/.dotnet":$PATH + export DOTNET_ROOT="$SCRIPT_DIR/.dotnet" +fi + +########################################################################### +# INSTALL CAKE +########################################################################### + +CAKE_INSTALLED_VERSION=$(dotnet-cake --version 2>&1) + +if [ "$CAKE_VERSION" != "$CAKE_INSTALLED_VERSION" ]; then + if [ ! -f "$CAKE_EXE" ] || [ ! -d "$CAKE_PATH" ]; then + if [ -f "$CAKE_EXE" ]; then + dotnet tool uninstall --tool-path $TOOLS_DIR Cake.Tool + fi + + echo "Installing Cake $CAKE_VERSION..." + dotnet tool install --tool-path $TOOLS_DIR --version $CAKE_VERSION Cake.Tool + if [ $? -ne 0 ]; then + echo "An error occured while installing Cake." + exit 1 + fi + fi + + # Make sure that Cake has been installed. + if [ ! -f "$CAKE_EXE" ]; then + echo "Could not find Cake.exe at '$CAKE_EXE'." + exit 1 + fi +else + CAKE_EXE="dotnet-cake" +fi + +########################################################################### +# RUN BUILD SCRIPT +########################################################################### + +# Start Cake +(exec "$CAKE_EXE" build.cake --bootstrap) && (exec "$CAKE_EXE" build.cake "$@") \ No newline at end of file diff --git a/codecov.sh b/codecov.sh new file mode 100644 index 0000000..9091d74 --- /dev/null +++ b/codecov.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +TOKEN=$1 +rm -r ./test/TestResults +rm -r CodeCoverage +for name in `ls ./test/*.csproj | awk '{print $NF}'`; +do + echo ${name} + dotnet test ${name} --logger trx --settings CodeCoverage.runsettings --collect:"XPlat Code Coverage" +done +reportgenerator /test/TestResults/*/coverage.cobertura.xml -reports:./test/TestResults/*/coverage.cobertura.xml -targetdir:./CodeCoverage -reporttypes:Cobertura -assemblyfilters:-xunit* +codecov -f ./CodeCoverage/Cobertura.xml -t ${TOKEN} \ No newline at end of file diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..23be405 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,3 @@ +codecov: + notify: + after_n_builds: 1 \ No newline at end of file diff --git a/src/AElf.KeyStore.csproj b/src/AElf.KeyStore.csproj new file mode 100644 index 0000000..d6a0528 --- /dev/null +++ b/src/AElf.KeyStore.csproj @@ -0,0 +1,15 @@ + + + + net7.0 + enable + enable + AElf.KeyStore + + + + + + + + \ No newline at end of file diff --git a/src/AElfKeyStoreService.cs b/src/AElfKeyStoreService.cs new file mode 100644 index 0000000..e64635d --- /dev/null +++ b/src/AElfKeyStoreService.cs @@ -0,0 +1,25 @@ +using AElf.Cryptography; +using AElf.Cryptography.Exceptions; +using AElf.Types; +using Nethereum.KeyStore; + +namespace AElf.KeyStore; + +public class AElfKeyStoreService : KeyStoreService +{ + + public string EncryptKeyStoreAsJson(string password, string privateKey) + { + var keyPair = CryptoHelper.FromPrivateKey(ByteArrayHelper.HexStringToByteArray(privateKey)); + var address = Address.FromPublicKey(keyPair.PublicKey); + return EncryptAndGenerateDefaultKeyStoreAsJson(password, keyPair.PrivateKey, address.ToBase58()); + } + + public byte[] DecryptKeyStoreFromFile(string password, string filePath) + { + using var file = File.OpenText(filePath); + var json = file.ReadToEnd(); + return DecryptKeyStoreFromJson(password, json); + } + +} \ No newline at end of file diff --git a/test/AElf.KeyStore.Tests.csproj b/test/AElf.KeyStore.Tests.csproj new file mode 100644 index 0000000..4f501ee --- /dev/null +++ b/test/AElf.KeyStore.Tests.csproj @@ -0,0 +1,34 @@ + + + + net7.0 + enable + enable + 11 + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + Always + + + + \ No newline at end of file diff --git a/test/AElfKeyStoreServiceTests.cs b/test/AElfKeyStoreServiceTests.cs new file mode 100644 index 0000000..feafa87 --- /dev/null +++ b/test/AElfKeyStoreServiceTests.cs @@ -0,0 +1,62 @@ +// ReSharper disable StringLiteralTypo +namespace AElf.KeyStore.Tests; + +public class AElfKeyStoreServiceTests +{ + private const string Password = "abcde"; + private const string PrivateKeyHex = "ff96c3463af0b8629f170f078f97ac0147490b92e1784e3bff93f7ee9d1abcb6"; + + [Fact] + public void EncryptKeyStoreAsJson_Test() + { + var keystoreService = new AElfKeyStoreService(); + var keystoreJson = keystoreService.EncryptKeyStoreAsJson( + Password, + PrivateKeyHex + ); + Assert.Contains("\"address\":\"VQFq9atg4fMtFLhqpVh48ZnhX8FXMGBHW8MDANPpCSHcZisU6\"", keystoreJson); + var privateKey = keystoreService.DecryptKeyStoreFromJson(Password, keystoreJson); + Assert.Equal(ByteArrayHelper.HexStringToByteArray(PrivateKeyHex), privateKey); + } + + [Fact] + public void DecryptKeyStoreFromJson_Test() + { + const string jsonKeyStore = + """ + { + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "1734a897caeea53e306fa6908fca443e598ea1cb6361fb27e5c45de61a26eb25", + "cipherparams": { + "iv": "36f00104f0488386db1f3e3d37b14bfe" + }, + "kdf": "scrypt", + "mac": "011ff2bee41f29f8fb6f7a63b1266bf04054bf1881e94cd3a77ead034ec47892", + "kdfparams": { + "n": 262144, + "r": 1, + "p": 8, + "dklen": 32, + "salt": "fd09ae033a9660eb1ad6a0bb0bf7b03ee30944c2fe621eef2a262fd3d2a92881" + } + }, + "id": "7b2aa039-291d-4e09-8f18-8d503fd7711a", + "address": "VQFq9atg4fMtFLhqpVh48ZnhX8FXMGBHW8MDANPpCSHcZisU6", + "version": 3 + } + """; + var keystoreService = new AElfKeyStoreService(); + var privateKey = keystoreService.DecryptKeyStoreFromJson(Password, jsonKeyStore); + Assert.Equal(ByteArrayHelper.HexStringToByteArray(PrivateKeyHex), privateKey); + } + + [Fact] + public void DecryptKeyStoreFromFile_Test() + { + var keystoreService = new AElfKeyStoreService(); + var privateKey = keystoreService.DecryptKeyStoreFromFile(Password, "data/VQFq9atg4fMtFLhqpVh48ZnhX8FXMGBHW8MDANPpCSHcZisU6.json"); + Assert.Equal(ByteArrayHelper.HexStringToByteArray(PrivateKeyHex), privateKey); + } + +} \ No newline at end of file diff --git a/test/GlobalUsings.cs b/test/GlobalUsings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/test/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/test/data/VQFq9atg4fMtFLhqpVh48ZnhX8FXMGBHW8MDANPpCSHcZisU6.json b/test/data/VQFq9atg4fMtFLhqpVh48ZnhX8FXMGBHW8MDANPpCSHcZisU6.json new file mode 100644 index 0000000..14dcccc --- /dev/null +++ b/test/data/VQFq9atg4fMtFLhqpVh48ZnhX8FXMGBHW8MDANPpCSHcZisU6.json @@ -0,0 +1,21 @@ +{ + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "1734a897caeea53e306fa6908fca443e598ea1cb6361fb27e5c45de61a26eb25", + "cipherparams": { + "iv": "36f00104f0488386db1f3e3d37b14bfe" + }, + "kdf": "scrypt", + "mac": "011ff2bee41f29f8fb6f7a63b1266bf04054bf1881e94cd3a77ead034ec47892", + "kdfparams": { + "n": 262144, + "r": 1, + "p": 8, + "dklen": 32, + "salt": "fd09ae033a9660eb1ad6a0bb0bf7b03ee30944c2fe621eef2a262fd3d2a92881" + } + }, + "id": "7b2aa039-291d-4e09-8f18-8d503fd7711a", + "address": "VQFq9atg4fMtFLhqpVh48ZnhX8FXMGBHW8MDANPpCSHcZisU6", + "version": 3 +} \ No newline at end of file