diff --git a/neo.sln b/neo.sln index 3779ae8d78..523849127d 100644 --- a/neo.sln +++ b/neo.sln @@ -1,4 +1,5 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 + +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.2.32516.85 MinimumVisualStudioVersion = 10.0.40219.1 @@ -88,164 +89,500 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Cryptography.MPTTrie.Te EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Network.RPC.Tests", "tests\Neo.Network.RPC.Tests\Neo.Network.RPC.Tests.csproj", "{19B1CF1A-17F4-4E04-AB9C-55CE74952E11}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Plugins.SignClient.Tests", "tests\Neo.Plugins.SignClient.Tests\Neo.Plugins.SignClient.Tests.csproj", "{61E46D13-9AB7-460E-8B34-65502E757059}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SignClient", "src\Plugins\SignClient\SignClient.csproj", "{BA754911-8945-41F1-89E4-BFE99FB0AB9D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Debug|x64.ActiveCfg = Debug|Any CPU + {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Debug|x64.Build.0 = Debug|Any CPU + {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Debug|x86.ActiveCfg = Debug|Any CPU + {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Debug|x86.Build.0 = Debug|Any CPU {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Release|Any CPU.ActiveCfg = Release|Any CPU {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Release|Any CPU.Build.0 = Release|Any CPU + {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Release|x64.ActiveCfg = Release|Any CPU + {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Release|x64.Build.0 = Release|Any CPU + {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Release|x86.ActiveCfg = Release|Any CPU + {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Release|x86.Build.0 = Release|Any CPU {6B709ED6-64C0-451D-B07F-8F49185AE191}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6B709ED6-64C0-451D-B07F-8F49185AE191}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B709ED6-64C0-451D-B07F-8F49185AE191}.Debug|x64.ActiveCfg = Debug|Any CPU + {6B709ED6-64C0-451D-B07F-8F49185AE191}.Debug|x64.Build.0 = Debug|Any CPU + {6B709ED6-64C0-451D-B07F-8F49185AE191}.Debug|x86.ActiveCfg = Debug|Any CPU + {6B709ED6-64C0-451D-B07F-8F49185AE191}.Debug|x86.Build.0 = Debug|Any CPU {6B709ED6-64C0-451D-B07F-8F49185AE191}.Release|Any CPU.ActiveCfg = Release|Any CPU {6B709ED6-64C0-451D-B07F-8F49185AE191}.Release|Any CPU.Build.0 = Release|Any CPU + {6B709ED6-64C0-451D-B07F-8F49185AE191}.Release|x64.ActiveCfg = Release|Any CPU + {6B709ED6-64C0-451D-B07F-8F49185AE191}.Release|x64.Build.0 = Release|Any CPU + {6B709ED6-64C0-451D-B07F-8F49185AE191}.Release|x86.ActiveCfg = Release|Any CPU + {6B709ED6-64C0-451D-B07F-8F49185AE191}.Release|x86.Build.0 = Release|Any CPU {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Debug|x64.ActiveCfg = Debug|Any CPU + {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Debug|x64.Build.0 = Debug|Any CPU + {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Debug|x86.ActiveCfg = Debug|Any CPU + {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Debug|x86.Build.0 = Debug|Any CPU {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Release|Any CPU.ActiveCfg = Release|Any CPU {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Release|Any CPU.Build.0 = Release|Any CPU + {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Release|x64.ActiveCfg = Release|Any CPU + {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Release|x64.Build.0 = Release|Any CPU + {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Release|x86.ActiveCfg = Release|Any CPU + {5B783B30-B422-4C2F-AC22-187A8D1993F4}.Release|x86.Build.0 = Release|Any CPU {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Debug|x64.ActiveCfg = Debug|Any CPU + {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Debug|x64.Build.0 = Debug|Any CPU + {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Debug|x86.ActiveCfg = Debug|Any CPU + {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Debug|x86.Build.0 = Debug|Any CPU {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Release|Any CPU.ActiveCfg = Release|Any CPU {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Release|Any CPU.Build.0 = Release|Any CPU + {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Release|x64.ActiveCfg = Release|Any CPU + {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Release|x64.Build.0 = Release|Any CPU + {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Release|x86.ActiveCfg = Release|Any CPU + {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Release|x86.Build.0 = Release|Any CPU {BCD03521-5F8F-4775-9ADF-FA361480804F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BCD03521-5F8F-4775-9ADF-FA361480804F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BCD03521-5F8F-4775-9ADF-FA361480804F}.Debug|x64.ActiveCfg = Debug|Any CPU + {BCD03521-5F8F-4775-9ADF-FA361480804F}.Debug|x64.Build.0 = Debug|Any CPU + {BCD03521-5F8F-4775-9ADF-FA361480804F}.Debug|x86.ActiveCfg = Debug|Any CPU + {BCD03521-5F8F-4775-9ADF-FA361480804F}.Debug|x86.Build.0 = Debug|Any CPU {BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|Any CPU.ActiveCfg = Release|Any CPU {BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|Any CPU.Build.0 = Release|Any CPU + {BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|x64.ActiveCfg = Release|Any CPU + {BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|x64.Build.0 = Release|Any CPU + {BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|x86.ActiveCfg = Release|Any CPU + {BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|x86.Build.0 = Release|Any CPU {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Debug|x64.ActiveCfg = Debug|Any CPU + {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Debug|x64.Build.0 = Debug|Any CPU + {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Debug|x86.ActiveCfg = Debug|Any CPU + {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Debug|x86.Build.0 = Debug|Any CPU {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Release|Any CPU.ActiveCfg = Release|Any CPU {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Release|Any CPU.Build.0 = Release|Any CPU + {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Release|x64.ActiveCfg = Release|Any CPU + {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Release|x64.Build.0 = Release|Any CPU + {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Release|x86.ActiveCfg = Release|Any CPU + {E83633BA-FCF0-4A1A-B5BC-42000E24D437}.Release|x86.Build.0 = Release|Any CPU {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Debug|x64.ActiveCfg = Debug|Any CPU + {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Debug|x64.Build.0 = Debug|Any CPU + {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Debug|x86.ActiveCfg = Debug|Any CPU + {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Debug|x86.Build.0 = Debug|Any CPU {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Release|Any CPU.ActiveCfg = Release|Any CPU {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Release|Any CPU.Build.0 = Release|Any CPU + {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Release|x64.ActiveCfg = Release|Any CPU + {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Release|x64.Build.0 = Release|Any CPU + {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Release|x86.ActiveCfg = Release|Any CPU + {0603710E-E0BA-494C-AA0F-6FB0C8A8C754}.Release|x86.Build.0 = Release|Any CPU {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Debug|x64.ActiveCfg = Debug|Any CPU + {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Debug|x64.Build.0 = Debug|Any CPU + {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Debug|x86.ActiveCfg = Debug|Any CPU + {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Debug|x86.Build.0 = Debug|Any CPU {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Release|Any CPU.ActiveCfg = Release|Any CPU {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Release|Any CPU.Build.0 = Release|Any CPU + {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Release|x64.ActiveCfg = Release|Any CPU + {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Release|x64.Build.0 = Release|Any CPU + {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Release|x86.ActiveCfg = Release|Any CPU + {005F84EB-EA2E-449F-930A-7B4173DDC7EC}.Release|x86.Build.0 = Release|Any CPU {9E886812-7243-48D8-BEAF-47AADC11C054}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9E886812-7243-48D8-BEAF-47AADC11C054}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E886812-7243-48D8-BEAF-47AADC11C054}.Debug|x64.ActiveCfg = Debug|Any CPU + {9E886812-7243-48D8-BEAF-47AADC11C054}.Debug|x64.Build.0 = Debug|Any CPU + {9E886812-7243-48D8-BEAF-47AADC11C054}.Debug|x86.ActiveCfg = Debug|Any CPU + {9E886812-7243-48D8-BEAF-47AADC11C054}.Debug|x86.Build.0 = Debug|Any CPU {9E886812-7243-48D8-BEAF-47AADC11C054}.Release|Any CPU.ActiveCfg = Release|Any CPU {9E886812-7243-48D8-BEAF-47AADC11C054}.Release|Any CPU.Build.0 = Release|Any CPU + {9E886812-7243-48D8-BEAF-47AADC11C054}.Release|x64.ActiveCfg = Release|Any CPU + {9E886812-7243-48D8-BEAF-47AADC11C054}.Release|x64.Build.0 = Release|Any CPU + {9E886812-7243-48D8-BEAF-47AADC11C054}.Release|x86.ActiveCfg = Release|Any CPU + {9E886812-7243-48D8-BEAF-47AADC11C054}.Release|x86.Build.0 = Release|Any CPU {02ABDE42-9880-43B4-B6F7-8D618602A277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {02ABDE42-9880-43B4-B6F7-8D618602A277}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02ABDE42-9880-43B4-B6F7-8D618602A277}.Debug|x64.ActiveCfg = Debug|Any CPU + {02ABDE42-9880-43B4-B6F7-8D618602A277}.Debug|x64.Build.0 = Debug|Any CPU + {02ABDE42-9880-43B4-B6F7-8D618602A277}.Debug|x86.ActiveCfg = Debug|Any CPU + {02ABDE42-9880-43B4-B6F7-8D618602A277}.Debug|x86.Build.0 = Debug|Any CPU {02ABDE42-9880-43B4-B6F7-8D618602A277}.Release|Any CPU.ActiveCfg = Release|Any CPU {02ABDE42-9880-43B4-B6F7-8D618602A277}.Release|Any CPU.Build.0 = Release|Any CPU + {02ABDE42-9880-43B4-B6F7-8D618602A277}.Release|x64.ActiveCfg = Release|Any CPU + {02ABDE42-9880-43B4-B6F7-8D618602A277}.Release|x64.Build.0 = Release|Any CPU + {02ABDE42-9880-43B4-B6F7-8D618602A277}.Release|x86.ActiveCfg = Release|Any CPU + {02ABDE42-9880-43B4-B6F7-8D618602A277}.Release|x86.Build.0 = Release|Any CPU {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Debug|x64.ActiveCfg = Debug|Any CPU + {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Debug|x64.Build.0 = Debug|Any CPU + {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Debug|x86.ActiveCfg = Debug|Any CPU + {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Debug|x86.Build.0 = Debug|Any CPU {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Release|Any CPU.ActiveCfg = Release|Any CPU {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Release|Any CPU.Build.0 = Release|Any CPU + {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Release|x64.ActiveCfg = Release|Any CPU + {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Release|x64.Build.0 = Release|Any CPU + {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Release|x86.ActiveCfg = Release|Any CPU + {BDFBE455-4C1F-4FC4-B5FC-1387B93A8687}.Release|x86.Build.0 = Release|Any CPU {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Debug|x64.ActiveCfg = Debug|Any CPU + {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Debug|x64.Build.0 = Debug|Any CPU + {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Debug|x86.ActiveCfg = Debug|Any CPU + {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Debug|x86.Build.0 = Debug|Any CPU {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Release|Any CPU.ActiveCfg = Release|Any CPU {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Release|Any CPU.Build.0 = Release|Any CPU + {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Release|x64.ActiveCfg = Release|Any CPU + {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Release|x64.Build.0 = Release|Any CPU + {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Release|x86.ActiveCfg = Release|Any CPU + {B40F8584-5AFB-452C-AEFA-009C80CC23A9}.Release|x86.Build.0 = Release|Any CPU {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Debug|x64.ActiveCfg = Debug|Any CPU + {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Debug|x64.Build.0 = Debug|Any CPU + {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Debug|x86.ActiveCfg = Debug|Any CPU + {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Debug|x86.Build.0 = Debug|Any CPU {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Release|Any CPU.ActiveCfg = Release|Any CPU {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Release|Any CPU.Build.0 = Release|Any CPU + {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Release|x64.ActiveCfg = Release|Any CPU + {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Release|x64.Build.0 = Release|Any CPU + {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Release|x86.ActiveCfg = Release|Any CPU + {D48C1FAB-3471-4CA0-8688-25E6F43F2C25}.Release|x86.Build.0 = Release|Any CPU {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Debug|x64.ActiveCfg = Debug|Any CPU + {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Debug|x64.Build.0 = Debug|Any CPU + {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Debug|x86.ActiveCfg = Debug|Any CPU + {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Debug|x86.Build.0 = Debug|Any CPU {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Release|Any CPU.ActiveCfg = Release|Any CPU {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Release|Any CPU.Build.0 = Release|Any CPU + {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Release|x64.ActiveCfg = Release|Any CPU + {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Release|x64.Build.0 = Release|Any CPU + {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Release|x86.ActiveCfg = Release|Any CPU + {387CCF6C-9A26-43F6-A639-0A82E91E10D8}.Release|x86.Build.0 = Release|Any CPU {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|x64.ActiveCfg = Debug|Any CPU + {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|x64.Build.0 = Debug|Any CPU + {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|x86.ActiveCfg = Debug|Any CPU + {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|x86.Build.0 = Debug|Any CPU {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|Any CPU.ActiveCfg = Release|Any CPU {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|Any CPU.Build.0 = Release|Any CPU + {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|x64.ActiveCfg = Release|Any CPU + {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|x64.Build.0 = Release|Any CPU + {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|x86.ActiveCfg = Release|Any CPU + {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|x86.Build.0 = Release|Any CPU {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|x64.ActiveCfg = Debug|Any CPU + {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|x64.Build.0 = Debug|Any CPU + {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|x86.ActiveCfg = Debug|Any CPU + {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|x86.Build.0 = Debug|Any CPU {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|Any CPU.ActiveCfg = Release|Any CPU {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|Any CPU.Build.0 = Release|Any CPU + {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|x64.ActiveCfg = Release|Any CPU + {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|x64.Build.0 = Release|Any CPU + {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|x86.ActiveCfg = Release|Any CPU + {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|x86.Build.0 = Release|Any CPU {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Debug|x64.ActiveCfg = Debug|Any CPU + {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Debug|x64.Build.0 = Debug|Any CPU + {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Debug|x86.ActiveCfg = Debug|Any CPU + {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Debug|x86.Build.0 = Debug|Any CPU {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Release|Any CPU.ActiveCfg = Release|Any CPU {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Release|Any CPU.Build.0 = Release|Any CPU + {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Release|x64.ActiveCfg = Release|Any CPU + {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Release|x64.Build.0 = Release|Any CPU + {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Release|x86.ActiveCfg = Release|Any CPU + {5D9764FB-827D-4DDE-84E3-3C05FD8ABC89}.Release|x86.Build.0 = Release|Any CPU {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Debug|x64.ActiveCfg = Debug|Any CPU + {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Debug|x64.Build.0 = Debug|Any CPU + {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Debug|x86.ActiveCfg = Debug|Any CPU + {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Debug|x86.Build.0 = Debug|Any CPU {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Release|Any CPU.ActiveCfg = Release|Any CPU {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Release|Any CPU.Build.0 = Release|Any CPU + {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Release|x64.ActiveCfg = Release|Any CPU + {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Release|x64.Build.0 = Release|Any CPU + {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Release|x86.ActiveCfg = Release|Any CPU + {2CBD2311-BA2E-4921-A000-FDDA59B74958}.Release|x86.Build.0 = Release|Any CPU {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Debug|x64.ActiveCfg = Debug|Any CPU + {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Debug|x64.Build.0 = Debug|Any CPU + {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Debug|x86.ActiveCfg = Debug|Any CPU + {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Debug|x86.Build.0 = Debug|Any CPU {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Release|Any CPU.ActiveCfg = Release|Any CPU {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Release|Any CPU.Build.0 = Release|Any CPU + {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Release|x64.ActiveCfg = Release|Any CPU + {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Release|x64.Build.0 = Release|Any CPU + {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Release|x86.ActiveCfg = Release|Any CPU + {EF01E062-DBBC-47AF-AF3B-9EDEB00CFF7C}.Release|x86.Build.0 = Release|Any CPU {22E2CE64-080B-4138-885F-7FA74A9159FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {22E2CE64-080B-4138-885F-7FA74A9159FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22E2CE64-080B-4138-885F-7FA74A9159FB}.Debug|x64.ActiveCfg = Debug|Any CPU + {22E2CE64-080B-4138-885F-7FA74A9159FB}.Debug|x64.Build.0 = Debug|Any CPU + {22E2CE64-080B-4138-885F-7FA74A9159FB}.Debug|x86.ActiveCfg = Debug|Any CPU + {22E2CE64-080B-4138-885F-7FA74A9159FB}.Debug|x86.Build.0 = Debug|Any CPU {22E2CE64-080B-4138-885F-7FA74A9159FB}.Release|Any CPU.ActiveCfg = Release|Any CPU {22E2CE64-080B-4138-885F-7FA74A9159FB}.Release|Any CPU.Build.0 = Release|Any CPU + {22E2CE64-080B-4138-885F-7FA74A9159FB}.Release|x64.ActiveCfg = Release|Any CPU + {22E2CE64-080B-4138-885F-7FA74A9159FB}.Release|x64.Build.0 = Release|Any CPU + {22E2CE64-080B-4138-885F-7FA74A9159FB}.Release|x86.ActiveCfg = Release|Any CPU + {22E2CE64-080B-4138-885F-7FA74A9159FB}.Release|x86.Build.0 = Release|Any CPU {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Debug|x64.ActiveCfg = Debug|Any CPU + {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Debug|x64.Build.0 = Debug|Any CPU + {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Debug|x86.ActiveCfg = Debug|Any CPU + {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Debug|x86.Build.0 = Debug|Any CPU {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Release|Any CPU.ActiveCfg = Release|Any CPU {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Release|Any CPU.Build.0 = Release|Any CPU + {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Release|x64.ActiveCfg = Release|Any CPU + {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Release|x64.Build.0 = Release|Any CPU + {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Release|x86.ActiveCfg = Release|Any CPU + {4C39E872-FC37-4BFD-AE4C-3E3F0546B726}.Release|x86.Build.0 = Release|Any CPU {4C4D8180-9326-486C-AECF-8368BBD0766A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4C4D8180-9326-486C-AECF-8368BBD0766A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C4D8180-9326-486C-AECF-8368BBD0766A}.Debug|x64.ActiveCfg = Debug|Any CPU + {4C4D8180-9326-486C-AECF-8368BBD0766A}.Debug|x64.Build.0 = Debug|Any CPU + {4C4D8180-9326-486C-AECF-8368BBD0766A}.Debug|x86.ActiveCfg = Debug|Any CPU + {4C4D8180-9326-486C-AECF-8368BBD0766A}.Debug|x86.Build.0 = Debug|Any CPU {4C4D8180-9326-486C-AECF-8368BBD0766A}.Release|Any CPU.ActiveCfg = Release|Any CPU {4C4D8180-9326-486C-AECF-8368BBD0766A}.Release|Any CPU.Build.0 = Release|Any CPU + {4C4D8180-9326-486C-AECF-8368BBD0766A}.Release|x64.ActiveCfg = Release|Any CPU + {4C4D8180-9326-486C-AECF-8368BBD0766A}.Release|x64.Build.0 = Release|Any CPU + {4C4D8180-9326-486C-AECF-8368BBD0766A}.Release|x86.ActiveCfg = Release|Any CPU + {4C4D8180-9326-486C-AECF-8368BBD0766A}.Release|x86.Build.0 = Release|Any CPU {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Debug|x64.ActiveCfg = Debug|Any CPU + {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Debug|x64.Build.0 = Debug|Any CPU + {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Debug|x86.ActiveCfg = Debug|Any CPU + {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Debug|x86.Build.0 = Debug|Any CPU {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Release|Any CPU.ActiveCfg = Release|Any CPU {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Release|Any CPU.Build.0 = Release|Any CPU + {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Release|x64.ActiveCfg = Release|Any CPU + {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Release|x64.Build.0 = Release|Any CPU + {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Release|x86.ActiveCfg = Release|Any CPU + {DE0FB77E-3099-4C88-BB7D-BFAED75D813E}.Release|x86.Build.0 = Release|Any CPU {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Debug|x64.ActiveCfg = Debug|Any CPU + {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Debug|x64.Build.0 = Debug|Any CPU + {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Debug|x86.ActiveCfg = Debug|Any CPU + {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Debug|x86.Build.0 = Debug|Any CPU {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Release|Any CPU.ActiveCfg = Release|Any CPU {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Release|Any CPU.Build.0 = Release|Any CPU + {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Release|x64.ActiveCfg = Release|Any CPU + {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Release|x64.Build.0 = Release|Any CPU + {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Release|x86.ActiveCfg = Release|Any CPU + {3DE59148-59D6-4CD3-8086-0BC74E3D4E0B}.Release|x86.Build.0 = Release|Any CPU {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Debug|x64.ActiveCfg = Debug|Any CPU + {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Debug|x64.Build.0 = Debug|Any CPU + {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Debug|x86.ActiveCfg = Debug|Any CPU + {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Debug|x86.Build.0 = Debug|Any CPU {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Release|Any CPU.ActiveCfg = Release|Any CPU {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Release|Any CPU.Build.0 = Release|Any CPU + {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Release|x64.ActiveCfg = Release|Any CPU + {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Release|x64.Build.0 = Release|Any CPU + {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Release|x86.ActiveCfg = Release|Any CPU + {A3941551-E72C-42D7-8C4D-5122CB60D73D}.Release|x86.Build.0 = Release|Any CPU {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Debug|x64.ActiveCfg = Debug|Any CPU + {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Debug|x64.Build.0 = Debug|Any CPU + {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Debug|x86.ActiveCfg = Debug|Any CPU + {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Debug|x86.Build.0 = Debug|Any CPU {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Release|Any CPU.ActiveCfg = Release|Any CPU {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Release|Any CPU.Build.0 = Release|Any CPU + {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Release|x64.ActiveCfg = Release|Any CPU + {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Release|x64.Build.0 = Release|Any CPU + {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Release|x86.ActiveCfg = Release|Any CPU + {F53D5FF0-5D3D-4E8B-A44F-C4C5D9B563B1}.Release|x86.Build.0 = Release|Any CPU {88975A8D-4797-45A4-BC3E-15962A425A54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {88975A8D-4797-45A4-BC3E-15962A425A54}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88975A8D-4797-45A4-BC3E-15962A425A54}.Debug|x64.ActiveCfg = Debug|Any CPU + {88975A8D-4797-45A4-BC3E-15962A425A54}.Debug|x64.Build.0 = Debug|Any CPU + {88975A8D-4797-45A4-BC3E-15962A425A54}.Debug|x86.ActiveCfg = Debug|Any CPU + {88975A8D-4797-45A4-BC3E-15962A425A54}.Debug|x86.Build.0 = Debug|Any CPU {88975A8D-4797-45A4-BC3E-15962A425A54}.Release|Any CPU.ActiveCfg = Release|Any CPU {88975A8D-4797-45A4-BC3E-15962A425A54}.Release|Any CPU.Build.0 = Release|Any CPU + {88975A8D-4797-45A4-BC3E-15962A425A54}.Release|x64.ActiveCfg = Release|Any CPU + {88975A8D-4797-45A4-BC3E-15962A425A54}.Release|x64.Build.0 = Release|Any CPU + {88975A8D-4797-45A4-BC3E-15962A425A54}.Release|x86.ActiveCfg = Release|Any CPU + {88975A8D-4797-45A4-BC3E-15962A425A54}.Release|x86.Build.0 = Release|Any CPU {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Debug|x64.ActiveCfg = Debug|Any CPU + {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Debug|x64.Build.0 = Debug|Any CPU + {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Debug|x86.ActiveCfg = Debug|Any CPU + {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Debug|x86.Build.0 = Debug|Any CPU {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Release|Any CPU.ActiveCfg = Release|Any CPU {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Release|Any CPU.Build.0 = Release|Any CPU + {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Release|x64.ActiveCfg = Release|Any CPU + {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Release|x64.Build.0 = Release|Any CPU + {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Release|x86.ActiveCfg = Release|Any CPU + {FF76D8A4-356B-461A-8471-BC1B83E57BBC}.Release|x86.Build.0 = Release|Any CPU {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Debug|x64.ActiveCfg = Debug|Any CPU + {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Debug|x64.Build.0 = Debug|Any CPU + {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Debug|x86.ActiveCfg = Debug|Any CPU + {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Debug|x86.Build.0 = Debug|Any CPU {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Release|Any CPU.ActiveCfg = Release|Any CPU {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Release|Any CPU.Build.0 = Release|Any CPU + {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Release|x64.ActiveCfg = Release|Any CPU + {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Release|x64.Build.0 = Release|Any CPU + {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Release|x86.ActiveCfg = Release|Any CPU + {5E4947F3-05D3-4806-B0F3-30DAC71B5986}.Release|x86.Build.0 = Release|Any CPU {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Debug|x64.ActiveCfg = Debug|Any CPU + {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Debug|x64.Build.0 = Debug|Any CPU + {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Debug|x86.ActiveCfg = Debug|Any CPU + {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Debug|x86.Build.0 = Debug|Any CPU {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Release|Any CPU.ActiveCfg = Release|Any CPU {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Release|Any CPU.Build.0 = Release|Any CPU + {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Release|x64.ActiveCfg = Release|Any CPU + {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Release|x64.Build.0 = Release|Any CPU + {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Release|x86.ActiveCfg = Release|Any CPU + {8C866DC8-2E55-4399-9563-2F47FD4602EC}.Release|x86.Build.0 = Release|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Debug|x64.ActiveCfg = Debug|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Debug|x64.Build.0 = Debug|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Debug|x86.ActiveCfg = Debug|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Debug|x86.Build.0 = Debug|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Release|Any CPU.Build.0 = Release|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Release|x64.ActiveCfg = Release|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Release|x64.Build.0 = Release|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Release|x86.ActiveCfg = Release|Any CPU + {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Release|x86.Build.0 = Release|Any CPU {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|x64.ActiveCfg = Debug|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|x64.Build.0 = Debug|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|x86.ActiveCfg = Debug|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|x86.Build.0 = Debug|Any CPU {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|Any CPU.ActiveCfg = Release|Any CPU {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|Any CPU.Build.0 = Release|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|x64.ActiveCfg = Release|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|x64.Build.0 = Release|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|x86.ActiveCfg = Release|Any CPU + {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|x86.Build.0 = Release|Any CPU {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Debug|x64.ActiveCfg = Debug|Any CPU + {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Debug|x64.Build.0 = Debug|Any CPU + {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Debug|x86.ActiveCfg = Debug|Any CPU + {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Debug|x86.Build.0 = Debug|Any CPU {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Release|Any CPU.ActiveCfg = Release|Any CPU {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Release|Any CPU.Build.0 = Release|Any CPU + {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Release|x64.ActiveCfg = Release|Any CPU + {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Release|x64.Build.0 = Release|Any CPU + {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Release|x86.ActiveCfg = Release|Any CPU + {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Release|x86.Build.0 = Release|Any CPU {5F984D2B-793F-4683-B53A-80050E6E0286}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5F984D2B-793F-4683-B53A-80050E6E0286}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5F984D2B-793F-4683-B53A-80050E6E0286}.Debug|x64.ActiveCfg = Debug|Any CPU + {5F984D2B-793F-4683-B53A-80050E6E0286}.Debug|x64.Build.0 = Debug|Any CPU + {5F984D2B-793F-4683-B53A-80050E6E0286}.Debug|x86.ActiveCfg = Debug|Any CPU + {5F984D2B-793F-4683-B53A-80050E6E0286}.Debug|x86.Build.0 = Debug|Any CPU {5F984D2B-793F-4683-B53A-80050E6E0286}.Release|Any CPU.ActiveCfg = Release|Any CPU {5F984D2B-793F-4683-B53A-80050E6E0286}.Release|Any CPU.Build.0 = Release|Any CPU - {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Debug|Any CPU.Build.0 = Debug|Any CPU - {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Release|Any CPU.ActiveCfg = Release|Any CPU - {72997EAB-9B0C-4BC8-B797-955C219C2C97}.Release|Any CPU.Build.0 = Release|Any CPU + {5F984D2B-793F-4683-B53A-80050E6E0286}.Release|x64.ActiveCfg = Release|Any CPU + {5F984D2B-793F-4683-B53A-80050E6E0286}.Release|x64.Build.0 = Release|Any CPU + {5F984D2B-793F-4683-B53A-80050E6E0286}.Release|x86.ActiveCfg = Release|Any CPU + {5F984D2B-793F-4683-B53A-80050E6E0286}.Release|x86.Build.0 = Release|Any CPU {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Debug|x64.ActiveCfg = Debug|Any CPU + {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Debug|x64.Build.0 = Debug|Any CPU + {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Debug|x86.ActiveCfg = Debug|Any CPU + {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Debug|x86.Build.0 = Debug|Any CPU {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Release|Any CPU.ActiveCfg = Release|Any CPU {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Release|Any CPU.Build.0 = Release|Any CPU + {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Release|x64.ActiveCfg = Release|Any CPU + {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Release|x64.Build.0 = Release|Any CPU + {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Release|x86.ActiveCfg = Release|Any CPU + {9ADB4E11-8655-42C2-8A75-E4436F56F17A}.Release|x86.Build.0 = Release|Any CPU {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Debug|x64.ActiveCfg = Debug|Any CPU + {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Debug|x64.Build.0 = Debug|Any CPU + {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Debug|x86.ActiveCfg = Debug|Any CPU + {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Debug|x86.Build.0 = Debug|Any CPU {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Release|Any CPU.ActiveCfg = Release|Any CPU {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Release|Any CPU.Build.0 = Release|Any CPU + {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Release|x64.ActiveCfg = Release|Any CPU + {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Release|x64.Build.0 = Release|Any CPU + {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Release|x86.ActiveCfg = Release|Any CPU + {E384C5EF-493E-4ED6-813C-6364F968CEE8}.Release|x86.Build.0 = Release|Any CPU {40A23D45-1E81-41A4-B587-16AF26630103}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {40A23D45-1E81-41A4-B587-16AF26630103}.Debug|Any CPU.Build.0 = Debug|Any CPU + {40A23D45-1E81-41A4-B587-16AF26630103}.Debug|x64.ActiveCfg = Debug|Any CPU + {40A23D45-1E81-41A4-B587-16AF26630103}.Debug|x64.Build.0 = Debug|Any CPU + {40A23D45-1E81-41A4-B587-16AF26630103}.Debug|x86.ActiveCfg = Debug|Any CPU + {40A23D45-1E81-41A4-B587-16AF26630103}.Debug|x86.Build.0 = Debug|Any CPU {40A23D45-1E81-41A4-B587-16AF26630103}.Release|Any CPU.ActiveCfg = Release|Any CPU {40A23D45-1E81-41A4-B587-16AF26630103}.Release|Any CPU.Build.0 = Release|Any CPU + {40A23D45-1E81-41A4-B587-16AF26630103}.Release|x64.ActiveCfg = Release|Any CPU + {40A23D45-1E81-41A4-B587-16AF26630103}.Release|x64.Build.0 = Release|Any CPU + {40A23D45-1E81-41A4-B587-16AF26630103}.Release|x86.ActiveCfg = Release|Any CPU + {40A23D45-1E81-41A4-B587-16AF26630103}.Release|x86.Build.0 = Release|Any CPU {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Debug|x64.ActiveCfg = Debug|Any CPU + {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Debug|x64.Build.0 = Debug|Any CPU + {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Debug|x86.ActiveCfg = Debug|Any CPU + {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Debug|x86.Build.0 = Debug|Any CPU {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Release|Any CPU.ActiveCfg = Release|Any CPU {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Release|Any CPU.Build.0 = Release|Any CPU + {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Release|x64.ActiveCfg = Release|Any CPU + {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Release|x64.Build.0 = Release|Any CPU + {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Release|x86.ActiveCfg = Release|Any CPU + {19B1CF1A-17F4-4E04-AB9C-55CE74952E11}.Release|x86.Build.0 = Release|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Debug|Any CPU.Build.0 = Debug|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Debug|x64.ActiveCfg = Debug|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Debug|x64.Build.0 = Debug|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Debug|x86.ActiveCfg = Debug|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Debug|x86.Build.0 = Debug|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Release|Any CPU.ActiveCfg = Release|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Release|Any CPU.Build.0 = Release|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Release|x64.ActiveCfg = Release|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Release|x64.Build.0 = Release|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Release|x86.ActiveCfg = Release|Any CPU + {61E46D13-9AB7-460E-8B34-65502E757059}.Release|x86.Build.0 = Release|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Debug|x64.ActiveCfg = Debug|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Debug|x64.Build.0 = Debug|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Debug|x86.ActiveCfg = Debug|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Debug|x86.Build.0 = Debug|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Release|Any CPU.Build.0 = Release|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Release|x64.ActiveCfg = Release|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Release|x64.Build.0 = Release|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Release|x86.ActiveCfg = Release|Any CPU + {BA754911-8945-41F1-89E4-BFE99FB0AB9D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -282,14 +619,16 @@ Global {FF76D8A4-356B-461A-8471-BC1B83E57BBC} = {C2DC830A-327A-42A7-807D-295216D30DBB} {5E4947F3-05D3-4806-B0F3-30DAC71B5986} = {C2DC830A-327A-42A7-807D-295216D30DBB} {8C866DC8-2E55-4399-9563-2F47FD4602EC} = {7F257712-D033-47FF-B439-9D4320D06599} + {72997EAB-9B0C-4BC8-B797-955C219C2C97} = {7F257712-D033-47FF-B439-9D4320D06599} {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1} {B6CB2559-10F9-41AC-8D58-364BFEF9688B} = {C25EB0B0-0CAC-4CC1-8F36-F9229EFB99EC} {5F984D2B-793F-4683-B53A-80050E6E0286} = {C25EB0B0-0CAC-4CC1-8F36-F9229EFB99EC} - {72997EAB-9B0C-4BC8-B797-955C219C2C97} = {7F257712-D033-47FF-B439-9D4320D06599} {9ADB4E11-8655-42C2-8A75-E4436F56F17A} = {B5339DF7-5D1D-43BA-B332-74B825E1770E} {E384C5EF-493E-4ED6-813C-6364F968CEE8} = {B5339DF7-5D1D-43BA-B332-74B825E1770E} {40A23D45-1E81-41A4-B587-16AF26630103} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1} {19B1CF1A-17F4-4E04-AB9C-55CE74952E11} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1} + {61E46D13-9AB7-460E-8B34-65502E757059} = {7F257712-D033-47FF-B439-9D4320D06599} + {BA754911-8945-41F1-89E4-BFE99FB0AB9D} = {C2DC830A-327A-42A7-807D-295216D30DBB} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BCBA19D9-F868-4C6D-8061-A2B91E06E3EC} diff --git a/src/Neo.CLI/CLI/MainService.Wallet.cs b/src/Neo.CLI/CLI/MainService.Wallet.cs index 9e75235d9b..9b6dbd3058 100644 --- a/src/Neo.CLI/CLI/MainService.Wallet.cs +++ b/src/Neo.CLI/CLI/MainService.Wallet.cs @@ -73,7 +73,7 @@ private void OnCloseWalletCommand() if (CurrentWallet is not null) { - SignerFactory.UnregisterSigner(CurrentWallet.Name); + SignerManager.UnregisterSigner(CurrentWallet.Name); } CurrentWallet = null; diff --git a/src/Neo.CLI/CLI/MainService.cs b/src/Neo.CLI/CLI/MainService.cs index 71c1cc82be..449fa9c14b 100644 --- a/src/Neo.CLI/CLI/MainService.cs +++ b/src/Neo.CLI/CLI/MainService.cs @@ -161,7 +161,7 @@ public void CreateWallet(string path, string password, bool createDefaultAccount wallet.Save(); CurrentWallet = wallet; - SignerFactory.RegisterSigner(wallet.Name, wallet); + SignerManager.RegisterSigner(wallet.Name, wallet); } private bool NoWallet() @@ -296,10 +296,10 @@ public void OpenWallet(string path, string password) throw new FileNotFoundException($"Wallet file \"{path}\" not found."); } - if (CurrentWallet is not null) SignerFactory.UnregisterSigner(CurrentWallet.Name); + if (CurrentWallet is not null) SignerManager.UnregisterSigner(CurrentWallet.Name); CurrentWallet = Wallet.Open(path, password, NeoSystem.Settings) ?? throw new NotSupportedException(); - SignerFactory.RegisterSigner(CurrentWallet.Name, CurrentWallet); + SignerManager.RegisterSigner(CurrentWallet.Name, CurrentWallet); } public async void Start(CommandLineOptions options) diff --git a/src/Neo/Sign/ISigner.cs b/src/Neo/Sign/ISigner.cs index 77fe2f82cd..0251387403 100644 --- a/src/Neo/Sign/ISigner.cs +++ b/src/Neo/Sign/ISigner.cs @@ -21,7 +21,7 @@ namespace Neo.Sign public interface ISigner { /// - /// Signs the with the wallet. + /// Signs the with the signer. /// /// The to be used. /// diff --git a/src/Neo/Sign/SignException.cs b/src/Neo/Sign/SignException.cs index 36bb8cc504..e734b6fb66 100644 --- a/src/Neo/Sign/SignException.cs +++ b/src/Neo/Sign/SignException.cs @@ -22,6 +22,7 @@ public class SignException : Exception /// Initializes a new instance of the class. /// /// The message that describes the error. - public SignException(string message) : base(message) { } + /// The cause of the exception. + public SignException(string message, Exception cause = null) : base(message, cause) { } } } diff --git a/src/Neo/Sign/SignerFactory.cs b/src/Neo/Sign/SignerManager.cs similarity index 96% rename from src/Neo/Sign/SignerFactory.cs rename to src/Neo/Sign/SignerManager.cs index ffe17b9c08..967fa6becf 100644 --- a/src/Neo/Sign/SignerFactory.cs +++ b/src/Neo/Sign/SignerManager.cs @@ -1,6 +1,6 @@ // Copyright (C) 2015-2025 The Neo Project. // -// SignerFactory.cs file belongs to the neo project and is free +// SignerManager.cs file belongs to the neo project and is free // software distributed under the MIT software license, see the // accompanying file LICENSE in the main directory of the // repository or http://www.opensource.org/licenses/mit-license.php @@ -15,7 +15,7 @@ namespace Neo.Sign { - public static class SignerFactory + public static class SignerManager { private static readonly ConcurrentDictionary s_signers = new(); diff --git a/src/Plugins/DBFTPlugin/DBFTPlugin.cs b/src/Plugins/DBFTPlugin/DBFTPlugin.cs index 206d4d22b7..7c7b203b52 100644 --- a/src/Plugins/DBFTPlugin/DBFTPlugin.cs +++ b/src/Plugins/DBFTPlugin/DBFTPlugin.cs @@ -87,7 +87,7 @@ void IWalletChangedHandler.IWalletProvider_WalletChanged_Handler(object sender, [ConsoleCommand("start consensus", Category = "Consensus", Description = "Start consensus service (dBFT)")] private void OnStart(string signerName = "") { - var signer = SignerFactory.GetSignerOrDefault(signerName); + var signer = SignerManager.GetSignerOrDefault(signerName); Start(signer ?? walletProvider.GetWallet()); } diff --git a/src/Plugins/SignClient/Settings.cs b/src/Plugins/SignClient/Settings.cs new file mode 100644 index 0000000000..6a09a4f89e --- /dev/null +++ b/src/Plugins/SignClient/Settings.cs @@ -0,0 +1,57 @@ +// Copyright (C) 2015-2025 The Neo Project. +// +// Settings.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Microsoft.Extensions.Configuration; +using System.Net; + +namespace Neo.Plugins.SignClient +{ + public class Settings : PluginSettings + { + /// + /// Only support local host at present, so host always is "127.0.0.1" or "::1" now. + /// + public static readonly string DefaultEndpoint = $"http://{IPAddress.Loopback}:9991"; + public const string SectionName = "PluginConfiguration"; + + /// + /// The name of the sign client(i.e. Signer). + /// + public readonly string Name; + + /// + /// The host of the sign client(i.e. Signer). + /// + public readonly string Endpoint; + + public Settings(IConfigurationSection section) : base(section) + { + Name = section.GetValue("Name", "SignClient"); + Endpoint = section.GetValue("Endpoint", DefaultEndpoint); + } + + public static Settings Default + { + get + { + var section = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + [SectionName + ":Name"] = "SignClient", + [SectionName + ":Endpoint"] = DefaultEndpoint + }) + .Build() + .GetSection(SectionName); + return new Settings(section); + } + } + } +} diff --git a/src/Plugins/SignClient/SignClient.cs b/src/Plugins/SignClient/SignClient.cs new file mode 100644 index 0000000000..395e9db7dd --- /dev/null +++ b/src/Plugins/SignClient/SignClient.cs @@ -0,0 +1,304 @@ +// Copyright (C) 2015-2025 The Neo Project. +// +// SignClient.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Google.Protobuf; +using Grpc.Core; +using Grpc.Net.Client; +using Grpc.Net.Client.Configuration; +using Neo.ConsoleService; +using Neo.Cryptography.ECC; +using Neo.Extensions; +using Neo.Network.P2P; +using Neo.Sign; +using Neo.SmartContract; +using Servicepb; +using Signpb; +using System.Diagnostics.CodeAnalysis; +using static Neo.SmartContract.Helper; + +namespace Neo.Plugins.SignClient +{ + /// + /// A signer that uses a client to sign transactions. + /// + public class SignClient : Plugin, ISigner + { + private GrpcChannel? _channel; + + private SecureSign.SecureSignClient? _client; + + private string _name = string.Empty; + + public override string Description => "Signer plugin for signer service."; + + public override string ConfigFile => System.IO.Path.Combine(RootPath, "SignClient.json"); + + public SignClient() { } + + public SignClient(Settings settings) + { + Reset(settings); + } + + // It's for test now. + internal SignClient(string name, SecureSign.SecureSignClient client) + { + Reset(name, client); + } + + private void Reset(string name, SecureSign.SecureSignClient? client) + { + if (_client is not null) SignerManager.UnregisterSigner(_name); + + _name = name; + _client = client; + if (!string.IsNullOrEmpty(_name)) SignerManager.RegisterSigner(_name, this); + } + + private void Reset(Settings settings) + { + // _settings = settings; + var methodConfig = new MethodConfig + { + Names = { MethodName.Default }, + RetryPolicy = new RetryPolicy + { + MaxAttempts = 3, + InitialBackoff = TimeSpan.FromMilliseconds(50), + MaxBackoff = TimeSpan.FromMilliseconds(200), + BackoffMultiplier = 1.5, + RetryableStatusCodes = { + StatusCode.Cancelled, + StatusCode.DeadlineExceeded, + StatusCode.ResourceExhausted, + StatusCode.Unavailable, + StatusCode.Aborted, + StatusCode.Internal, + StatusCode.DataLoss, + StatusCode.Unknown + } + } + }; + + var channel = GrpcChannel.ForAddress(settings.Endpoint, new GrpcChannelOptions + { + ServiceConfig = new ServiceConfig { MethodConfigs = { methodConfig } } + }); + + _channel?.Dispose(); + _channel = channel; + Reset(settings.Name, new SecureSign.SecureSignClient(_channel)); + } + + /// + /// Get account status command + /// + /// The hex public key, compressed or uncompressed + [ConsoleCommand("get account status", Category = "Signer Commands", Description = "Get account status")] + public void AccountStatusCommand(string hexPublicKey) + { + if (_client is null) + { + ConsoleHelper.Error("No signer service is connected"); + return; + } + + try + { + var publicKey = ECPoint.DecodePoint(hexPublicKey.HexToBytes(), ECCurve.Secp256r1); + var output = _client.GetAccountStatus(new() + { + PublicKey = ByteString.CopyFrom(publicKey.EncodePoint(true)) + }); + ConsoleHelper.Info($"Account status: {output.Status}"); + } + catch (RpcException rpcEx) + { + if (rpcEx.StatusCode == StatusCode.Unavailable) + { + ConsoleHelper.Error("No available signer service"); + } + else + { + ConsoleHelper.Error($"Failed to get account status: {rpcEx.StatusCode}: {rpcEx.Status.Detail}"); + } + } + catch (FormatException formatEx) + { + ConsoleHelper.Error($"Invalid public key: {formatEx.Message}"); + } + } + + private AccountStatus GetAccountStatus(ECPoint publicKey) + { + if (_client is null) throw new SignException("No signer service is connected"); + + try + { + var output = _client.GetAccountStatus(new() + { + PublicKey = ByteString.CopyFrom(publicKey.EncodePoint(true)) + }); + return output.Status; + } + catch (RpcException ex) + { + throw new SignException($"Get account status: {ex.Status}", ex); + } + } + + /// + /// Check if the account is signable + /// + /// The public key + /// True if the account is signable, false otherwise + /// If no signer service is available, or other rpc error occurs. + public bool ContainsSignable(ECPoint publicKey) + { + var status = GetAccountStatus(publicKey); + return status == AccountStatus.Single || status == AccountStatus.Multiple; + } + + private static bool TryDecodePublicKey(ByteString publicKey, [NotNullWhen(true)] out ECPoint? point) + { + try + { + point = ECPoint.DecodePoint(publicKey.Span, ECCurve.Secp256r1); + } + catch (FormatException) // add log later + { + point = null; + } + return point is not null; + } + + internal bool Sign(ContractParametersContext context, IEnumerable signs) + { + var succeed = false; + foreach (var (accountSigns, scriptHash) in signs.Zip(context.ScriptHashes)) + { + var accountStatus = accountSigns.Status; + if (accountStatus == AccountStatus.NoSuchAccount || accountStatus == AccountStatus.NoPrivateKey) + { + succeed |= context.AddWithScriptHash(scriptHash); // Same as Wallet.Sign(context) + continue; + } + + var contract = accountSigns.Contract; + var accountContract = Contract.Create( + contract?.Parameters?.Select(p => (ContractParameterType)p).ToArray() ?? [], + contract?.Script?.ToByteArray() ?? []); + if (accountStatus == AccountStatus.Multiple) + { + if (!IsMultiSigContract(accountContract.Script, out int m, out ECPoint[] publicKeys)) + throw new SignException("Sign context: multi-sign account but not multi-sign contract"); + + foreach (var sign in accountSigns.Signs) + { + if (!TryDecodePublicKey(sign.PublicKey, out var publicKey)) continue; + + if (!publicKeys.Contains(publicKey)) + throw new SignException($"Sign context: public key {publicKey} not in multi-sign contract"); + + var ok = context.AddSignature(accountContract, publicKey, sign.Signature.ToByteArray()); + if (ok) m--; + + succeed |= ok; + if (context.Completed || m <= 0) break; + } + } + else if (accountStatus == AccountStatus.Single) + { + if (accountSigns.Signs is null || accountSigns.Signs.Count != 1) + throw new SignException($"Sign context: single account but {accountSigns.Signs?.Count} signs"); + + var sign = accountSigns.Signs[0]; + if (!TryDecodePublicKey(sign.PublicKey, out var publicKey)) continue; + succeed |= context.AddSignature(accountContract, publicKey, sign.Signature.ToByteArray()); + } + } + return succeed; + } + + /// + /// Signs the with the signer. + /// + /// The context of the transaction + /// True if the transaction is signed, false otherwise + /// If no signer service is available, or other rpc error occurs. + public bool Sign(ContractParametersContext context) + { + if (_client is null) throw new SignException("No signer service is connected"); + + try + { + var signData = context.Verifiable.GetSignData(context.Network); + var output = _client.SignWithScriptHashes(new() + { + SignData = ByteString.CopyFrom(signData), + ScriptHashes = { context.ScriptHashes.Select(h160 => ByteString.CopyFrom(h160.GetSpan())) } + }); + + int signCount = output.Signs.Count, hashCount = context.ScriptHashes.Count; + if (signCount != hashCount) + { + throw new SignException($"Sign context: Signs.Count({signCount}) != Hashes.Count({hashCount})"); + } + return Sign(context, output.Signs); + } + catch (RpcException ex) + { + throw new SignException($"Sign context: {ex.Status}", ex); + } + } + + /// + /// Signs the specified data with the corresponding private key of the specified public key. + /// + /// The data to sign + /// The public key + /// The signature + /// If no signer service is available, or other rpc error occurs. + public ReadOnlyMemory Sign(byte[] signData, ECPoint publicKey) + { + if (_client is null) throw new SignException("No signer service is connected"); + + try + { + var output = _client.SignWithPublicKey(new() + { + SignData = ByteString.CopyFrom(signData), + PublicKey = ByteString.CopyFrom(publicKey.EncodePoint(true)), + }); + return output.Signature.Memory; + } + catch (RpcException ex) + { + throw new SignException($"Sign with public key: {ex.Status}", ex); + } + } + + /// + protected override void Configure() + { + var config = GetConfiguration(); + if (config is not null) Reset(new Settings(config)); + } + + /// + public override void Dispose() + { + Reset(string.Empty, null); + _channel?.Dispose(); + base.Dispose(); + } + } +} diff --git a/src/Plugins/SignClient/SignClient.csproj b/src/Plugins/SignClient/SignClient.csproj new file mode 100644 index 0000000000..36e289e3b4 --- /dev/null +++ b/src/Plugins/SignClient/SignClient.csproj @@ -0,0 +1,34 @@ + + + + net9.0 + latest + enable + enable + + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Plugins/SignClient/SignClient.json b/src/Plugins/SignClient/SignClient.json new file mode 100644 index 0000000000..35cdb5a074 --- /dev/null +++ b/src/Plugins/SignClient/SignClient.json @@ -0,0 +1,6 @@ +{ + "PluginConfiguration": { + "Name": "SignClient", + "EndPoint": "http://127.0.0.1:9991" + } +} diff --git a/src/Plugins/SignClient/proto/servicepb.proto b/src/Plugins/SignClient/proto/servicepb.proto new file mode 100644 index 0000000000..43d3b2685b --- /dev/null +++ b/src/Plugins/SignClient/proto/servicepb.proto @@ -0,0 +1,58 @@ +// Copyright (C) 2015-2025 The Neo Project. +// +// servicepb.proto file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +syntax = "proto3"; + +import "signpb.proto"; + +package servicepb; + +message SignWithScriptHashesRequest { + // the data to be signed + bytes sign_data = 1; + + // script hashes, H160 + repeated bytes script_hashes = 3; +} + +message SignWithScriptHashesResponse { + // script_hash -> script_hash_signs + repeated signpb.AccountSigns signs = 1; +} + +message SignWithPublicKeyRequest { + // the data to be signed + bytes sign_data = 1; + + // compressed or uncompressed public key + bytes public_key = 3; +} + +message SignWithPublicKeyResponse { + bytes signature = 1; +} + +message GetAccountStatusRequest { + // compressed or uncompressed public key + bytes public_key = 1; +} + +message GetAccountStatusResponse { + signpb.AccountStatus status = 1; +} + +service SecureSign { + rpc SignWithScriptHashes(SignWithScriptHashesRequest) returns (SignWithScriptHashesResponse) {} + + rpc SignWithPublicKey(SignWithPublicKeyRequest) returns (SignWithPublicKeyResponse) {} + + rpc GetAccountStatus(GetAccountStatusRequest) returns (GetAccountStatusResponse) {} +} diff --git a/src/Plugins/SignClient/proto/signpb.proto b/src/Plugins/SignClient/proto/signpb.proto new file mode 100644 index 0000000000..0b058eacd7 --- /dev/null +++ b/src/Plugins/SignClient/proto/signpb.proto @@ -0,0 +1,64 @@ +// Copyright (C) 2015-2025 The Neo Project. +// +// signpb.proto file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +syntax = "proto3"; + +package signpb; + +message AccountSign { + // the signature + bytes signature = 1; + + // the compressed or uncompressed public key + bytes public_key = 2; +} + +message AccountContract { + // the contract script + bytes script = 1; + + // the contract parameters + repeated uint32 parameters = 2; + + // if the contract is deployed + bool deployed = 3; +} + +enum AccountStatus { + /// no such account + NoSuchAccount = 0; + + /// no private key + NoPrivateKey = 1; + + /// single sign + Single = 2; + + /// multiple signs, aka. multisig + Multiple = 3; + + /// this key-pair is locked + Locked = 4; +} + +message AccountSigns { + // if the status is Single, there is only one sign + // if the status is Multiple, there are multiple signs + // if the status is NoSuchAccount, NoPrivateKey or Locked, there are no signs + repeated AccountSign signs = 1; + + // the account contract + // If the account hasn't a contract, the contract is null + AccountContract contract = 2; + + // the account status + AccountStatus status = 3; +} diff --git a/tests/Neo.Plugins.SignClient.Tests/Neo.Plugins.SignClient.Tests.csproj b/tests/Neo.Plugins.SignClient.Tests/Neo.Plugins.SignClient.Tests.csproj new file mode 100644 index 0000000000..5e0cd293ef --- /dev/null +++ b/tests/Neo.Plugins.SignClient.Tests/Neo.Plugins.SignClient.Tests.csproj @@ -0,0 +1,20 @@ + + + + Exe + net9.0 + latest + enable + enable + + + + + + + + + + + + diff --git a/tests/Neo.Plugins.SignClient.Tests/UT_SignClient.cs b/tests/Neo.Plugins.SignClient.Tests/UT_SignClient.cs new file mode 100644 index 0000000000..b0b0c7dc1f --- /dev/null +++ b/tests/Neo.Plugins.SignClient.Tests/UT_SignClient.cs @@ -0,0 +1,195 @@ +// Copyright (C) 2015-2025 The Neo Project. +// +// UT_SignClient.cs file belongs to the neo project and is free +// software distributed under the MIT software license, see the +// accompanying file LICENSE in the main directory of the +// repository or http://www.opensource.org/licenses/mit-license.php +// for more details. +// +// Redistribution and use in source and binary forms with or without +// modifications are permitted. + +using Google.Protobuf; +using Grpc.Core; +using Microsoft.Extensions.Configuration; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Neo.Cryptography; +using Neo.Cryptography.ECC; +using Neo.Extensions; +using Neo.Network.P2P.Payloads; +using Neo.Persistence; +using Neo.Persistence.Providers; +using Neo.Sign; +using Neo.SmartContract; +using Neo.Wallets; +using Servicepb; +using Signpb; + +namespace Neo.Plugins.SignClient.Tests +{ + [TestClass] + public class UT_SignClient + { + const string PrivateKey = "0101010101010101010101010101010101010101010101010101010101010101"; + const string PublicKey = "026ff03b949241ce1dadd43519e6960e0a85b41a69a05c328103aa2bce1594ca16"; + const uint TestNetwork = 0x334F454Eu; + + private static readonly ECPoint s_publicKey = ECPoint.DecodePoint(PublicKey.HexToBytes(), ECCurve.Secp256r1); + + private static SignClient NewClient() + { + // for test sign service, set SIGN_SERVICE_ENDPOINT env + var endPoint = Environment.GetEnvironmentVariable("SIGN_SERVICE_ENDPOINT"); + if (endPoint is not null) + { + var section = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + [Settings.SectionName + ":Name"] = "SignClient", + [Settings.SectionName + ":EndPoint"] = endPoint + }) + .Build() + .GetSection(Settings.SectionName); + return new SignClient(new Settings(section)); + } + + var mockClient = new Mock(); + + // setup GetAccountStatus + mockClient.Setup(c => c.GetAccountStatus( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()) + ) + .Returns((req, _, _, _) => + { + if (req.PublicKey.ToByteArray().ToHexString() == PublicKey) + return new GetAccountStatusResponse() { Status = AccountStatus.Single }; + return new GetAccountStatusResponse() { Status = AccountStatus.NoSuchAccount }; + }); + + // setup SignWithPublicKey + mockClient.Setup(c => c.SignWithPublicKey( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()) + ) + .Returns((req, _, _, _) => + { + if (req.PublicKey.ToByteArray().ToHexString() == PublicKey) + { + var sign = Crypto.Sign(req.SignData.ToByteArray(), PrivateKey.HexToBytes(), ECCurve.Secp256r1); + return new SignWithPublicKeyResponse() { Signature = ByteString.CopyFrom(sign) }; + } + throw new RpcException(new Status(StatusCode.NotFound, "no such account")); + }); + + // setup SignWithScriptHashes + mockClient.Setup(c => c.SignWithScriptHashes( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()) + ) + .Returns((req, _, _, _) => + { + var script = Contract.CreateSignatureRedeemScript(s_publicKey); + var res = new SignWithScriptHashesResponse(); + foreach (var scriptHash in req.ScriptHashes) + { + if (scriptHash.ToByteArray().ToHexString() == script.ToScriptHash().GetSpan().ToHexString()) + { + var contract = new AccountContract() { Script = ByteString.CopyFrom(script) }; + contract.Parameters.Add((uint)ContractParameterType.Signature); + + var sign = Crypto.Sign(req.SignData.ToByteArray(), PrivateKey.HexToBytes(), ECCurve.Secp256r1); + var signs = new AccountSigns() { Status = AccountStatus.Single, Contract = contract }; + signs.Signs.Add(new AccountSign() + { + PublicKey = ByteString.CopyFrom(s_publicKey.EncodePoint(false).ToArray()), + Signature = ByteString.CopyFrom(sign) + }); + + res.Signs.Add(signs); + } + else + { + res.Signs.Add(new AccountSigns() { Status = AccountStatus.NoSuchAccount }); + } + } + return res; + }); + + return new SignClient("TestSignClient", mockClient.Object); + } + + [TestMethod] + public void TestSignPublicKey() + { + using var signClient = NewClient(); + + // sign with public key + var signature = signClient.Sign([1, 2, 3], s_publicKey); + Assert.IsNotNull(signature); + + // verify signature + var verified = Crypto.VerifySignature([1, 2, 3], signature.Span, s_publicKey); + Assert.IsTrue(verified); + + var privateKey = Enumerable.Repeat((byte)0x0f, 32).ToArray(); + var keypair = new KeyPair(privateKey); + + // sign with a not exists private key + var action = () => { _ = signClient.Sign([1, 2, 3], keypair.PublicKey); }; + Assert.ThrowsExactly(action); + } + + [TestMethod] + public void TestSignContext() + { + using var signClient = NewClient(); + using var store = new MemoryStore(); + using var snapshot = new StoreCache(store, false); + + // get account of the public key + var script = Contract.CreateSignatureRedeemScript(s_publicKey); + var tx = new Transaction + { + Script = script, + Signers = [new() { Account = script.ToScriptHash() }], + Attributes = [], + Witnesses = [Witness.Empty], + }; + + var context = new ContractParametersContext(snapshot, tx, TestNetwork); + var ok = signClient.Sign(context); + Assert.IsTrue(ok); + } + + [TestMethod] + public void TestGetAccountStatus() + { + using var signClient = NewClient(); + + // exists + var contains = signClient.ContainsSignable(s_publicKey); + Assert.IsTrue(contains); + + var privateKey = Enumerable.Repeat((byte)0x0f, 32).ToArray(); + var keypair = new KeyPair(privateKey); + + // not exists + contains = signClient.ContainsSignable(keypair.PublicKey); + Assert.IsFalse(contains); + + // exists + signClient.AccountStatusCommand(PublicKey); + + // not exists + signClient.AccountStatusCommand(keypair.PublicKey.EncodePoint(true).ToHexString()); + } + } +}