From 98c25397be22e9e0e22fe47a6aa64fce891fd0aa Mon Sep 17 00:00:00 2001 From: xiangxx Date: Mon, 10 Feb 2020 18:03:38 +0800 Subject: [PATCH 01/70] add generateKeyPairInfo --- AElf.Client.Test/ClientTest.cs | 8 ++++++++ AElf.Client/Protobuf/Proto/client.proto | 6 ++++++ AElf.Client/Service/AElfClient.cs | 19 ++++++++++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 58b6212..5d82d45 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -448,6 +448,14 @@ public async Task GetFormattedAddress_Test() Assert.True(result == $"ELF_{_address}_AELF"); } + [Fact] + public void GetNewKeyPairInfo_Test() + { + var output = Client.GenerateKeyPairInfo(); + var addressOutput = JsonConvert.SerializeObject(output); + _testOutputHelper.WriteLine(addressOutput); + } + #endregion #region private methods diff --git a/AElf.Client/Protobuf/Proto/client.proto b/AElf.Client/Protobuf/Proto/client.proto index bde9631..6fc60d5 100644 --- a/AElf.Client/Protobuf/Proto/client.proto +++ b/AElf.Client/Protobuf/Proto/client.proto @@ -46,6 +46,12 @@ message SmartContractRegistration { Hash code_hash = 3; } +message KeyPairInfo{ + string private_key = 1; + string public_key = 2; + string address = 3; +} + //acs0 message ContractInfo { diff --git a/AElf.Client/Service/AElfClient.cs b/AElf.Client/Service/AElfClient.cs index 88c13f4..a907fb3 100644 --- a/AElf.Client/Service/AElfClient.cs +++ b/AElf.Client/Service/AElfClient.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using AElf.Client.Dto; +using AElf.Client.Proto; using AElf.Cryptography; using AElf.Cryptography.ECDSA; using AElf.Types; @@ -19,6 +20,7 @@ public interface IClientService Task GetGenesisContractAddressAsync(); Task
GetContractAddressByName(Hash contractNameHash); string GetAddressFromPubKey(string pubKey); + KeyPairInfo GenerateKeyPairInfo(); } public partial class AElfClient : IClientService @@ -200,6 +202,21 @@ public Address GetBase58String(string base58String) return AddressHelper.Base58StringToAddress(base58String); } + public KeyPairInfo GenerateKeyPairInfo() + { + var keyPair = CryptoHelper.GenerateKeyPair(); + var privateKey = keyPair.PrivateKey.ToHex(); + var publicKey = keyPair.PublicKey.ToHex(); + var address = GetAddressFromPrivateKey(privateKey); + + return new KeyPairInfo + { + PrivateKey = privateKey, + PublicKey = publicKey, + Address = address + }; + } + #region private methods private ECKeyPair GetAElfKeyPair(string privateKeyHex) @@ -209,7 +226,7 @@ private ECKeyPair GetAElfKeyPair(string privateKeyHex) return keyPair; } - + private string GetRequestUrl(string baseUrl, string relativeUrl) { return new Uri(new Uri(baseUrl + (baseUrl.EndsWith("/") ? "" : "/")), relativeUrl).ToString(); From a1378c9d640d272ec00fb812d7fc940ef6d78033 Mon Sep 17 00:00:00 2001 From: xiangxx Date: Mon, 10 Feb 2020 19:40:40 +0800 Subject: [PATCH 02/70] move keyPairInfo to model --- AElf.Client/Model/KeyPairInfo.cs | 9 +++++++++ AElf.Client/Protobuf/Proto/client.proto | 6 ------ AElf.Client/Service/AElfClient.cs | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 AElf.Client/Model/KeyPairInfo.cs diff --git a/AElf.Client/Model/KeyPairInfo.cs b/AElf.Client/Model/KeyPairInfo.cs new file mode 100644 index 0000000..dda2aae --- /dev/null +++ b/AElf.Client/Model/KeyPairInfo.cs @@ -0,0 +1,9 @@ +namespace AElf.Client.Model +{ + public class KeyPairInfo + { + public string PrivateKey { get; set; } + public string PublicKey { get; set; } + public string Address { get; set; } + } +} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/client.proto b/AElf.Client/Protobuf/Proto/client.proto index 6fc60d5..bde9631 100644 --- a/AElf.Client/Protobuf/Proto/client.proto +++ b/AElf.Client/Protobuf/Proto/client.proto @@ -46,12 +46,6 @@ message SmartContractRegistration { Hash code_hash = 3; } -message KeyPairInfo{ - string private_key = 1; - string public_key = 2; - string address = 3; -} - //acs0 message ContractInfo { diff --git a/AElf.Client/Service/AElfClient.cs b/AElf.Client/Service/AElfClient.cs index a907fb3..fce755c 100644 --- a/AElf.Client/Service/AElfClient.cs +++ b/AElf.Client/Service/AElfClient.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Threading.Tasks; using AElf.Client.Dto; -using AElf.Client.Proto; +using AElf.Client.Model; using AElf.Cryptography; using AElf.Cryptography.ECDSA; using AElf.Types; From 5c0b6039f7f77178e086a803ef7a0caf9eb70a2d Mon Sep 17 00:00:00 2001 From: xiangxx Date: Mon, 10 Feb 2020 19:42:09 +0800 Subject: [PATCH 03/70] remove currentRoundInfo --- AElf.Client.Test/ClientTest.cs | 11 ----------- AElf.Client/Service/ChainAppService.cs | 12 ------------ 2 files changed, 23 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 5d82d45..a9e819b 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -117,17 +117,6 @@ public async Task GetContractFileDescriptorSetAsync_Test() descriptorSet.ShouldNotBeNull(); } - [Fact(Skip = "Redo this later.")] - public async Task GetCurrentRoundInformationAsync_Test() - { - var webAppService = new AElfClient(BaseUrl, 60); - var roundDto = await webAppService.GetCurrentRoundInformationAsync(); - roundDto.ShouldNotBeNull(); - - var currentRoundInformation = JsonConvert.SerializeObject(roundDto); - _testOutputHelper.WriteLine(currentRoundInformation); - } - #endregion #region net diff --git a/AElf.Client/Service/ChainAppService.cs b/AElf.Client/Service/ChainAppService.cs index b5eb743..79f9d48 100644 --- a/AElf.Client/Service/ChainAppService.cs +++ b/AElf.Client/Service/ChainAppService.cs @@ -10,8 +10,6 @@ public interface IChainAppService Task GetContractFileDescriptorSetAsync(string address); - Task GetCurrentRoundInformationAsync(); - Task> GetTaskQueueStatusAsync(); Task GetChainIdAsync(); @@ -41,16 +39,6 @@ public async Task GetContractFileDescriptorSetAsync(string address) return await _httpService.GetResponseAsync(url); } - /// - /// Get the latest round of consensus information from data on the last blockHeader of best-chain. - /// - /// The latest round of consensus information - public async Task GetCurrentRoundInformationAsync() - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/currentRoundInformation"); - return await _httpService.GetResponseAsync(url); - } - /// /// Gets the status information of the task queue. /// From ca4c93703a1e882839812d4f253396fd67797aa1 Mon Sep 17 00:00:00 2001 From: xiangxx Date: Fri, 14 Feb 2020 18:48:31 +0800 Subject: [PATCH 04/70] remove fileDescriptor --- AElf.Client.Test/AElf.Client.Test.csproj | 8 ++++---- AElf.Client.Test/ClientTest.cs | 12 +----------- AElf.Client/AElf.Client.csproj | 8 ++++---- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/AElf.Client.Test/AElf.Client.Test.csproj b/AElf.Client.Test/AElf.Client.Test.csproj index 7e630c7..a6d2091 100644 --- a/AElf.Client.Test/AElf.Client.Test.csproj +++ b/AElf.Client.Test/AElf.Client.Test.csproj @@ -1,14 +1,14 @@ - netcoreapp3.0 + netcoreapp3.1 false - - - + + + diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index a9e819b..781a4a4 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -5,7 +5,6 @@ using AElf.Cryptography; using AElf.Types; using AElf.Client.Dto; -using AElf.Client.Runtime; using AElf.Client.Service; using Google.Protobuf; using Newtonsoft.Json; @@ -21,7 +20,7 @@ namespace AElf.Client.Test { public class ClientTest { - private const string BaseUrl = "Http://127.0.0.1:8200"; + private const string BaseUrl = "Http://127.0.0.1:8001"; private string _genesisAddress; private string GenesisAddress => GetGenesisContractAddress(); @@ -108,15 +107,6 @@ public async Task GetChainStatusAsync_Test() _testOutputHelper.WriteLine(chainStatus); } - [Fact] - public async Task GetContractFileDescriptorSetAsync_Test() - { - var contractAddress = GenesisAddress; - var fileDescriptorBytes = await Client.GetContractFileDescriptorSetAsync(contractAddress); - var descriptorSet = FileDescriptorSet.Parser.ParseFrom(fileDescriptorBytes); - descriptorSet.ShouldNotBeNull(); - } - #endregion #region net diff --git a/AElf.Client/AElf.Client.csproj b/AElf.Client/AElf.Client.csproj index 29af607..18ffa2d 100644 --- a/AElf.Client/AElf.Client.csproj +++ b/AElf.Client/AElf.Client.csproj @@ -1,7 +1,7 @@ - netcoreapp3.0 + netcoreapp3.1 AElf.Client This is a C# client library, used to communicate with the AElf API. AElf @@ -11,13 +11,13 @@ - + - - + + From d3320177a165a1a83c13f6a1489724d08524d848 Mon Sep 17 00:00:00 2001 From: wudameinv <53204268+wudameinv@users.noreply.github.com> Date: Mon, 17 Feb 2020 21:00:51 +0800 Subject: [PATCH 05/70] Set up CI with Azure Pipelines [skip ci] --- azure-pipelines.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..9ae04d1 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,34 @@ +# ASP.NET Core (.NET Framework) +# Build and test ASP.NET Core projects targeting the full .NET Framework. +# Add steps that publish symbols, save build artifacts, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core + +trigger: +- master + +pool: + vmImage: 'windows-latest' + +variables: + solution: '**/*.sln' + buildPlatform: 'Any CPU' + buildConfiguration: 'Release' + +steps: +- task: NuGetToolInstaller@1 + +- task: NuGetCommand@2 + inputs: + restoreSolution: '$(solution)' + +- task: VSBuild@1 + inputs: + solution: '$(solution)' + msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"' + platform: '$(buildPlatform)' + configuration: '$(buildConfiguration)' + +- task: VSTest@2 + inputs: + platform: '$(buildPlatform)' + configuration: '$(buildConfiguration)' From cf71c6646e3c6361b00a624e62caaca54d881271 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 17 Feb 2020 13:12:52 +0000 Subject: [PATCH 06/70] add build.cake --- azure-pipelines.yml | 83 +++++++++++------- build.cake | 68 ++++++++++++++ singlecp/.test.sh.swo | Bin 0 -> 12288 bytes singlecp/.test.sh.swp | Bin 0 -> 12288 bytes singlecp/appsettings.MainChain.TestNet.json | 13 +++ singlecp/appsettings.json | 52 +++++++++++ singlecp/deploy_aelf.sh | 17 ++++ ...Nd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json | 1 + 8 files changed, 200 insertions(+), 34 deletions(-) create mode 100755 build.cake create mode 100644 singlecp/.test.sh.swo create mode 100644 singlecp/.test.sh.swp create mode 100644 singlecp/appsettings.MainChain.TestNet.json create mode 100644 singlecp/appsettings.json create mode 100644 singlecp/deploy_aelf.sh create mode 100644 singlecp/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 9ae04d1..1c66a99 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,34 +1,49 @@ -# ASP.NET Core (.NET Framework) -# Build and test ASP.NET Core projects targeting the full .NET Framework. -# Add steps that publish symbols, save build artifacts, and more: -# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core - -trigger: -- master - -pool: - vmImage: 'windows-latest' - -variables: - solution: '**/*.sln' - buildPlatform: 'Any CPU' - buildConfiguration: 'Release' - -steps: -- task: NuGetToolInstaller@1 - -- task: NuGetCommand@2 - inputs: - restoreSolution: '$(solution)' - -- task: VSBuild@1 - inputs: - solution: '$(solution)' - msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"' - platform: '$(buildPlatform)' - configuration: '$(buildConfiguration)' - -- task: VSTest@2 - inputs: - platform: '$(buildPlatform)' - configuration: '$(buildConfiguration)' +jobs: +# All tasks on Windows.... +- job: build_all_windows + displayName: Build all tasks (Windows) + pool: + vmImage: windows-2019 + variables: + CI_TEST: true + steps: + - task: DotNetCoreInstaller@0 + inputs: + version: '3.1.101' + - powershell: dotnet tool install --global Cake.Tool + - powershell: dotnet tool restore + - powershell: dotnet cake ./build.cake --target=build +# All tasks on Linux +- job: build_all_linux + displayName: Build all tasks (Linux) + pool: + vmImage: ubuntu-16.04 + steps: + - task: DotNetCoreInstaller@0 + inputs: + version: '3.1.101' + - script: dotnet tool install --global Cake.Tool + displayName: 'Install "Cake.Tool" .NET Core global tool' + - script: export PATH="$PATH:$HOME/.dotnet/tools" + - script: export PATH="$HOME/.dotnet:$PATH" + - script: dotnet tool restore + - script: dotnet cake ./build.cake --target=build + - script: cd singlecp && bash deploy_aelf.sh + - script: dotnet cake ./build.cake --target=test +# All tasks on macOS +- job: build_all_darwin + displayName: Build all tasks (macOS) + pool: + vmImage: macos-10.13 + variables: + CI_TEST: true + steps: + - task: DotNetCoreInstaller@0 + inputs: + version: '3.1.101' + - script: dotnet tool install --global Cake.Tool + displayName: 'Install "Cake.Tool" .NET Core global tool' + - script: export PATH="$PATH:$HOME/.dotnet/tools" + - script: export PATH="$HOME/.dotnet:$PATH" + - script: dotnet tool restore + - script: dotnet cake ./build.cake --target=build diff --git a/build.cake b/build.cake new file mode 100755 index 0000000..3fbe6d1 --- /dev/null +++ b/build.cake @@ -0,0 +1,68 @@ +var target = Argument("target", "default"); +var rootPath = "./"; +var srcPath = rootPath + "AElf.Client/"; +var testPath = rootPath + "AElf.Client.Test/"; +var distPath = rootPath + "aelf-node/"; +var solution = rootPath + "AElf.Client.sln"; +var srcProjects = GetFiles(srcPath + "AElf.Client.csproj"); + +Task("clean") + .Description("clean up project cache") + .Does(() => +{ + DeleteFiles(distPath + "*.nupkg"); + CleanDirectories(srcPath + "bin"); + CleanDirectories(srcPath + "obj"); + CleanDirectories(testPath + "bin"); + CleanDirectories(testPath + "obj"); +}); + +Task("restore") + .Description("restore project dependencies") + .Does(() => +{ + var restoreSettings = new DotNetCoreRestoreSettings{ + ArgumentCustomization = args => { + return args.Append("-v quiet");} +}; + DotNetCoreRestore(solution,restoreSettings); +}); + +Task("build") + .Description("Compilation project") + .IsDependentOn("clean") + .IsDependentOn("restore") + .Does(() => +{ + var buildSetting = new DotNetCoreBuildSettings{ + NoRestore = true, + Configuration = "Debug", + ArgumentCustomization = args => { + return args.Append("/clp:ErrorsOnly") + .Append("--no-incremental") + .Append("-v quiet");} + }; + + DotNetCoreBuild(solution, buildSetting); +}); +Task("test") + .Description("operation test") + .Does(() => +{ + var testSetting = new DotNetCoreTestSettings{ + NoRestore = true, + NoBuild = true +}; + var testProjects = GetFiles("./*.Test/*.csproj"); + + foreach(var testProject in testProjects) + { + DotNetCoreTest(testProject.FullPath, testSetting); + } +}); + +Task("default") + .Description("default run test(-target test)") + .IsDependentOn("build"); + +RunTarget(target); diff --git a/singlecp/.test.sh.swo b/singlecp/.test.sh.swo new file mode 100644 index 0000000000000000000000000000000000000000..16a8f117845939e8cb6190879406bad3203ac129 GIT binary patch literal 12288 zcmeI2Pp=y_5Wrn-h_;}X6B5!ic}h-R?`LA z?9cb_efRvzFYH;$SX0-|5C2!uh9{E|A18duuTM_b7PWCA*RE)nLaK7bZMKe5E3B^a zQl&;XWnE;8(=E^p5g-C*BG9@OpI&+}9wp(b_j}ji>Xip)GDVAs01+SpM1Tko0U|&I zhyW2dp9Gw_z@DP(@9o{cy00(%quzI^A_7E!2oM1xKm>>Y5g-CYfCvx)B0vPrApw~& zcIyMien#>C{~!PU|Kmf(UZMPi@(|?{l;18hHb?pE5@Wxj9HC554pA>Y5g-CYfCvx)BJe*FNHY*cy-{LoofW&fS&Kwi!Bkq*&?}VA z3kTZ5LD%fDuAVQ_wkd&ID4a7hAr7>eP2)Hb(rB?P>va8jA$8R?zX)a)%$7J+?F9bBRTS8_H7H zLN+R70EbE72E0$+vDkMGu`%;6;5#@m=yw#}^vv&ADaW^QbR!y}hrS2+O-6inyIe*0 zWm~0%YND(x-}ngAmSyn#U3NOnrL+a;$~sw=-&>n4F(Dal-UQ(`MwE3Pxks239moXN zyb2=Nm{K|=LeHvZi^O;ao%e66L}^{EIwMvgQVm1fpJM4Bjwd(z`4GBt$`0>bo~dP< z_f^x>&Djhjqe&Fwll1)?A8+PgJ@8S9Io&WA1Rl^)Utkemj4A|Gm*DVkg^o>vuUu0fuMI@$l0%PgUdeN~d@*A^tH8 z_vz;da3gf4CIzA(FN!TQ(4(%*TE GboMtA^qPeL literal 0 HcmV?d00001 diff --git a/singlecp/.test.sh.swp b/singlecp/.test.sh.swp new file mode 100644 index 0000000000000000000000000000000000000000..3e9fc0e17203dc4ee0be0916bf1fa1f1fdcd6a7e GIT binary patch literal 12288 zcmeI2Pp{KP5Wtt-s`gQ!hpM+BiIUTL?L?3e=}}b(1c*viB~VXQHr|cB#IY^!IuR|1 zPr;RQ4;7z*1D}B#=Sn@d*Q&GYJm@RDR(hvCX>5)6|IF-fb`Mcz89%u54a}mL;d6np zKR&+u!^=xQvp<)NHC5$&_kTU6=E-!-CkdbNE7Ox_i>h`aGcIqJLh540ty)K^71oql zq0?G8ZCzyZlQqx?5g-DmBG9@OpB>zvjFWKH`@PHX`K9}(Qbmi101+SpM1Tko0U|&I zhyW2dn*>~ajy*-!Kia#0abKSMN4alOK?H~Z5g-CYfCvx)B0vO)01+SpM1TmKK>|`S zcJC9$enIj7{~!JS|NS$@enWYV@(|?!<;8i%zCd|>z}PdC2PhX&e*KiO9?F*}Z&1&x zBYkI(2f0iHhyW2F0z`la5CI}U1pY4sQUxNfHd<`0vtm~@Ymo>mm`?Kwdbu`P?!Z_W zbk!c~%ELw4HU)4CxpVbgh=Hl+vp7zKtc_R}Rl2^BOH+2$+d<8O*+T0YCNZQPDc_}vAS;&sw#_eQoMOIxRxW>Sl`=xPs25_oqZ@RjxWERwE|^Bio5)`ylUt&@oU+wX4Py7T?v`}X1bbr4E#Md>4i zi^IVle6=?gMeLnho!(uBA;+^=ag21j=BaL+S(y|A77ja}xqZSpg53zCwA{79VIi9| zH(M?Kwx=#^61Uyf%BvU-vBABKBj3YDWa}y)W`JdD3dOaxx^zYs7}_jN_ptb*WBWOF zCVEz2#(XqMqFHoh>Mx|odVojQYUeN;-bN2?RRS~h;R0bxcnn#C*HODXhR2~gGI-oa vI3Rax;I{;feyST&Iv6BRMqTgQp7E2>g5kwHT+}94!QRQtaGBr}!w literal 0 HcmV?d00001 diff --git a/singlecp/appsettings.MainChain.TestNet.json b/singlecp/appsettings.MainChain.TestNet.json new file mode 100644 index 0000000..e97f765 --- /dev/null +++ b/singlecp/appsettings.MainChain.TestNet.json @@ -0,0 +1,13 @@ +{ +"ChainId": "AELF", + "Economic": { + "Symbol": "ELF", + "TokenName": "elf token", + "TotalSupply": 100000000000000000, + "Decimals": 8, + "IsBurnable": true, + "DividendPoolRatio": 0.12, + "MinimumLockTime": 7776000, + "MaximumLockTime": 93312000 + } +} diff --git a/singlecp/appsettings.json b/singlecp/appsettings.json new file mode 100644 index 0000000..4819e2c --- /dev/null +++ b/singlecp/appsettings.json @@ -0,0 +1,52 @@ +{ + "ChainId": "AELF", + "ChainType": "MainChain", + "NetType": "TestNet", + "AllowedHosts": "*", + "CorsOrigins": "*", + "ConnectionStrings": { + "BlockchainDb": "redis://172.31.8.57:6379", + "StateDb": "redis://172.31.8.57:6379" + }, + "Account": { + "NodeAccount": "SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM", + "NodeAccountPassword": "123" + }, + "Network": { + "BootNodes": [ + ], + "ListeningPort": 6800, + "NetAllowed": "", + "NetWhitelist": [] + }, + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://*:8000/" + } + } + }, + "Runner": { + "BlackList": [], + "WhiteList": [] + }, + "Consensus": { + "InitialMinerList": [ + ], + "MiningInterval": 4000, + "StartTimestamp": "0", + "TimeEachTerm": 604800, + "MinerIncreaseInterval": 31536000 + }, + "Transaction": { + "PoolLimit": 10240 + }, + "CrossChain": { + "Grpc": { + "ListeningPort": 5001 + } + }, + "Contract": { + "ContractDeploymentAuthorityRequired": "true" + } +} diff --git a/singlecp/deploy_aelf.sh b/singlecp/deploy_aelf.sh new file mode 100644 index 0000000..ea71cef --- /dev/null +++ b/singlecp/deploy_aelf.sh @@ -0,0 +1,17 @@ +#!/bin/bash +dir=`pwd` +ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` +sudo sed -i "s/172.31.8.57/$ip/g" appsettings.json +sudo apt update &&apt-get install make autoconf build-essential gcc unzip -y >>/dev/null +cd /opt && sudo wget --no-check-certificate https://github.com/ideawu/ssdb/archive/master.zip >>/dev/null +cd /opt &&sudo unzip master.zip && cd /opt/ssdb-master/ &&sudo make >>/dev/null && sudo make install PREFIX=/opt/ssdb-template /dev/null && cd .. +sudo sed -i 's#127.0.0.1#0.0.0.0#g' /opt/ssdb-template/ssdb.conf +sudo sed -i 's#debug#error#g' /opt/ssdb-template/ssdb.conf +sudo sed -i 's#8888#6379#g' /opt/ssdb-template/ssdb.conf +sudo /opt/ssdb-template/ssdb-server -d /opt/ssdb-template/ssdb.conf +sudo docker pull aelf/node:testnet-v0.9.2 +sudo docker run -itd --name aelf-node-test -v $dir:/opt/node -v $dir/keys:/root/.local/share/aelf/keys -p 8001:8000 -p 6800:6800 -w /opt/node aelf/node:testnet-v0.9.2 dotnet /app/AElf.Launcher.dll +sleep 30 +height=`curl -s http://$ip:8001/api/blockChain/blockHeight` +echo "height is $height" +cd $dir diff --git a/singlecp/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json b/singlecp/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json new file mode 100644 index 0000000..82dbef8 --- /dev/null +++ b/singlecp/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json @@ -0,0 +1 @@ +{"crypto":{"cipher":"aes-128-ctr","ciphertext":"6bed2f92088d090861e38f909047d2b68d1b3d1ec1913781916d12ae336bde59","cipherparams":{"iv":"9ac23ad68f7b0f34d1541a062b02693f"},"kdf":"scrypt","mac":"0b5b0b3b50d52c0061742077a47b6600008b3fc6c1a00c75095d07f07f3571cf","kdfparams":{"n":262144,"r":1,"p":8,"dklen":32,"salt":"4b27b913bb54a1cfe5195fb8bddcff3b5afc26a6f3fb387adb3bf0c63e7eed48"}},"id":"ee802828-4993-4b6f-b47c-fdba2100767f","address":"SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM","version":3} \ No newline at end of file From d278ec4dc8d6a98fc5923aac5157320758fc5ae1 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 17 Feb 2020 13:13:38 +0000 Subject: [PATCH 07/70] add build.cake --- singlecp/.test.sh.swo | Bin 12288 -> 0 bytes singlecp/.test.sh.swp | Bin 12288 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 singlecp/.test.sh.swo delete mode 100644 singlecp/.test.sh.swp diff --git a/singlecp/.test.sh.swo b/singlecp/.test.sh.swo deleted file mode 100644 index 16a8f117845939e8cb6190879406bad3203ac129..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2Pp=y_5Wrn-h_;}X6B5!ic}h-R?`LA z?9cb_efRvzFYH;$SX0-|5C2!uh9{E|A18duuTM_b7PWCA*RE)nLaK7bZMKe5E3B^a zQl&;XWnE;8(=E^p5g-C*BG9@OpI&+}9wp(b_j}ji>Xip)GDVAs01+SpM1Tko0U|&I zhyW2dp9Gw_z@DP(@9o{cy00(%quzI^A_7E!2oM1xKm>>Y5g-CYfCvx)B0vPrApw~& zcIyMien#>C{~!PU|Kmf(UZMPi@(|?{l;18hHb?pE5@Wxj9HC554pA>Y5g-CYfCvx)BJe*FNHY*cy-{LoofW&fS&Kwi!Bkq*&?}VA z3kTZ5LD%fDuAVQ_wkd&ID4a7hAr7>eP2)Hb(rB?P>va8jA$8R?zX)a)%$7J+?F9bBRTS8_H7H zLN+R70EbE72E0$+vDkMGu`%;6;5#@m=yw#}^vv&ADaW^QbR!y}hrS2+O-6inyIe*0 zWm~0%YND(x-}ngAmSyn#U3NOnrL+a;$~sw=-&>n4F(Dal-UQ(`MwE3Pxks239moXN zyb2=Nm{K|=LeHvZi^O;ao%e66L}^{EIwMvgQVm1fpJM4Bjwd(z`4GBt$`0>bo~dP< z_f^x>&Djhjqe&Fwll1)?A8+PgJ@8S9Io&WA1Rl^)Utkemj4A|Gm*DVkg^o>vuUu0fuMI@$l0%PgUdeN~d@*A^tH8 z_vz;da3gf4CIzA(FN!TQ(4(%*TE GboMtA^qPeL diff --git a/singlecp/.test.sh.swp b/singlecp/.test.sh.swp deleted file mode 100644 index 3e9fc0e17203dc4ee0be0916bf1fa1f1fdcd6a7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2Pp{KP5Wtt-s`gQ!hpM+BiIUTL?L?3e=}}b(1c*viB~VXQHr|cB#IY^!IuR|1 zPr;RQ4;7z*1D}B#=Sn@d*Q&GYJm@RDR(hvCX>5)6|IF-fb`Mcz89%u54a}mL;d6np zKR&+u!^=xQvp<)NHC5$&_kTU6=E-!-CkdbNE7Ox_i>h`aGcIqJLh540ty)K^71oql zq0?G8ZCzyZlQqx?5g-DmBG9@OpB>zvjFWKH`@PHX`K9}(Qbmi101+SpM1Tko0U|&I zhyW2dn*>~ajy*-!Kia#0abKSMN4alOK?H~Z5g-CYfCvx)B0vO)01+SpM1TmKK>|`S zcJC9$enIj7{~!JS|NS$@enWYV@(|?!<;8i%zCd|>z}PdC2PhX&e*KiO9?F*}Z&1&x zBYkI(2f0iHhyW2F0z`la5CI}U1pY4sQUxNfHd<`0vtm~@Ymo>mm`?Kwdbu`P?!Z_W zbk!c~%ELw4HU)4CxpVbgh=Hl+vp7zKtc_R}Rl2^BOH+2$+d<8O*+T0YCNZQPDc_}vAS;&sw#_eQoMOIxRxW>Sl`=xPs25_oqZ@RjxWERwE|^Bio5)`ylUt&@oU+wX4Py7T?v`}X1bbr4E#Md>4i zi^IVle6=?gMeLnho!(uBA;+^=ag21j=BaL+S(y|A77ja}xqZSpg53zCwA{79VIi9| zH(M?Kwx=#^61Uyf%BvU-vBABKBj3YDWa}y)W`JdD3dOaxx^zYs7}_jN_ptb*WBWOF zCVEz2#(XqMqFHoh>Mx|odVojQYUeN;-bN2?RRS~h;R0bxcnn#C*HODXhR2~gGI-oa vI3Rax;I{;feyST&Iv6BRMqTgQp7E2>g5kwHT+}94!QRQtaGBr}!w From f739e6b4fd270bc92d6d59ff4fccc70d6d305dff Mon Sep 17 00:00:00 2001 From: root Date: Tue, 18 Feb 2020 07:59:10 +0000 Subject: [PATCH 08/70] update yml --- azure-pipelines.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1c66a99..a86de78 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,18 +1,4 @@ jobs: -# All tasks on Windows.... -- job: build_all_windows - displayName: Build all tasks (Windows) - pool: - vmImage: windows-2019 - variables: - CI_TEST: true - steps: - - task: DotNetCoreInstaller@0 - inputs: - version: '3.1.101' - - powershell: dotnet tool install --global Cake.Tool - - powershell: dotnet tool restore - - powershell: dotnet cake ./build.cake --target=build # All tasks on Linux - job: build_all_linux displayName: Build all tasks (Linux) @@ -30,20 +16,3 @@ jobs: - script: dotnet cake ./build.cake --target=build - script: cd singlecp && bash deploy_aelf.sh - script: dotnet cake ./build.cake --target=test -# All tasks on macOS -- job: build_all_darwin - displayName: Build all tasks (macOS) - pool: - vmImage: macos-10.13 - variables: - CI_TEST: true - steps: - - task: DotNetCoreInstaller@0 - inputs: - version: '3.1.101' - - script: dotnet tool install --global Cake.Tool - displayName: 'Install "Cake.Tool" .NET Core global tool' - - script: export PATH="$PATH:$HOME/.dotnet/tools" - - script: export PATH="$HOME/.dotnet:$PATH" - - script: dotnet tool restore - - script: dotnet cake ./build.cake --target=build From a026ab89719904165e90f98e3a25088a3e945a8d Mon Sep 17 00:00:00 2001 From: root Date: Tue, 18 Feb 2020 09:15:07 +0000 Subject: [PATCH 09/70] update yml --- azure-pipelines.yml | 17 +++++----- build.cake | 1 + build.config | 3 ++ build.sh | 75 +++++++++++++++++++++++++++++++++++++++++ deploy_aelf.sh | 9 +++++ singlecp/deploy_aelf.sh | 8 ----- 6 files changed, 97 insertions(+), 16 deletions(-) create mode 100644 build.config create mode 100644 build.sh create mode 100644 deploy_aelf.sh diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a86de78..a9700d4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -2,17 +2,18 @@ jobs: # All tasks on Linux - job: build_all_linux displayName: Build all tasks (Linux) + services: + redis: + image: redis + ports: + - 6379:6379 pool: vmImage: ubuntu-16.04 steps: - task: DotNetCoreInstaller@0 inputs: version: '3.1.101' - - script: dotnet tool install --global Cake.Tool - displayName: 'Install "Cake.Tool" .NET Core global tool' - - script: export PATH="$PATH:$HOME/.dotnet/tools" - - script: export PATH="$HOME/.dotnet:$PATH" - - script: dotnet tool restore - - script: dotnet cake ./build.cake --target=build - - script: cd singlecp && bash deploy_aelf.sh - - script: dotnet cake ./build.cake --target=test + - script: cd singlecp && bash deploy_aelf.sh + displayName: 'Deploy a full node' + - script: bash build.sh -target=test + displayName: 'build and test' diff --git a/build.cake b/build.cake index 3fbe6d1..3f1db00 100755 --- a/build.cake +++ b/build.cake @@ -47,6 +47,7 @@ Task("build") }); Task("test") .Description("operation test") + .IsDependentOn("build") .Does(() => { var testSetting = new DotNetCoreTestSettings{ diff --git a/build.config b/build.config new file mode 100644 index 0000000..803c029 --- /dev/null +++ b/build.config @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +CAKE_VERSION=0.37.0 +DOTNET_VERSION=3.1.101 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/deploy_aelf.sh b/deploy_aelf.sh new file mode 100644 index 0000000..4ecb1ab --- /dev/null +++ b/deploy_aelf.sh @@ -0,0 +1,9 @@ +#!/bin/bash +dir=`pwd` +ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` +sudo sed -i "s/172.31.8.57/$ip/g" appsettings.json +sudo docker pull aelf/node:testnet-v0.9.2 +sudo docker run -itd --name aelf-node-test -v $dir:/opt/node -v $dir/keys:/root/.local/share/aelf/keys -p 8001:8000 -p 6800:6800 -w /opt/node aelf/node:testnet-v0.9.2 dotnet /app/AElf.Launcher.dll +sleep 30 +height=`curl -s http://$ip:8001/api/blockChain/blockHeight` +echo "height is $height" diff --git a/singlecp/deploy_aelf.sh b/singlecp/deploy_aelf.sh index ea71cef..4ecb1ab 100644 --- a/singlecp/deploy_aelf.sh +++ b/singlecp/deploy_aelf.sh @@ -2,16 +2,8 @@ dir=`pwd` ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` sudo sed -i "s/172.31.8.57/$ip/g" appsettings.json -sudo apt update &&apt-get install make autoconf build-essential gcc unzip -y >>/dev/null -cd /opt && sudo wget --no-check-certificate https://github.com/ideawu/ssdb/archive/master.zip >>/dev/null -cd /opt &&sudo unzip master.zip && cd /opt/ssdb-master/ &&sudo make >>/dev/null && sudo make install PREFIX=/opt/ssdb-template /dev/null && cd .. -sudo sed -i 's#127.0.0.1#0.0.0.0#g' /opt/ssdb-template/ssdb.conf -sudo sed -i 's#debug#error#g' /opt/ssdb-template/ssdb.conf -sudo sed -i 's#8888#6379#g' /opt/ssdb-template/ssdb.conf -sudo /opt/ssdb-template/ssdb-server -d /opt/ssdb-template/ssdb.conf sudo docker pull aelf/node:testnet-v0.9.2 sudo docker run -itd --name aelf-node-test -v $dir:/opt/node -v $dir/keys:/root/.local/share/aelf/keys -p 8001:8000 -p 6800:6800 -w /opt/node aelf/node:testnet-v0.9.2 dotnet /app/AElf.Launcher.dll sleep 30 height=`curl -s http://$ip:8001/api/blockChain/blockHeight` echo "height is $height" -cd $dir From 23bd05c7097c3f6a78037ca7616edbc39b8cdde9 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 18 Feb 2020 09:29:22 +0000 Subject: [PATCH 10/70] update filename --- azure-pipelines.yml | 2 +- .../aelf-node}/appsettings.MainChain.TestNet.json | 0 {singlecp => scripts/aelf-node}/appsettings.json | 0 ...D6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json | 0 deploy_aelf.sh => scripts/aelf-node/start.sh | 0 singlecp/deploy_aelf.sh | 9 --------- 6 files changed, 1 insertion(+), 10 deletions(-) rename {singlecp => scripts/aelf-node}/appsettings.MainChain.TestNet.json (100%) rename {singlecp => scripts/aelf-node}/appsettings.json (100%) rename {singlecp => scripts/aelf-node}/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json (100%) rename deploy_aelf.sh => scripts/aelf-node/start.sh (100%) delete mode 100644 singlecp/deploy_aelf.sh diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a9700d4..bc9ce8f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -13,7 +13,7 @@ jobs: - task: DotNetCoreInstaller@0 inputs: version: '3.1.101' - - script: cd singlecp && bash deploy_aelf.sh + - script: cd scripts/aelf-node && bash start.sh displayName: 'Deploy a full node' - script: bash build.sh -target=test displayName: 'build and test' diff --git a/singlecp/appsettings.MainChain.TestNet.json b/scripts/aelf-node/appsettings.MainChain.TestNet.json similarity index 100% rename from singlecp/appsettings.MainChain.TestNet.json rename to scripts/aelf-node/appsettings.MainChain.TestNet.json diff --git a/singlecp/appsettings.json b/scripts/aelf-node/appsettings.json similarity index 100% rename from singlecp/appsettings.json rename to scripts/aelf-node/appsettings.json diff --git a/singlecp/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json b/scripts/aelf-node/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json similarity index 100% rename from singlecp/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json rename to scripts/aelf-node/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json diff --git a/deploy_aelf.sh b/scripts/aelf-node/start.sh similarity index 100% rename from deploy_aelf.sh rename to scripts/aelf-node/start.sh diff --git a/singlecp/deploy_aelf.sh b/singlecp/deploy_aelf.sh deleted file mode 100644 index 4ecb1ab..0000000 --- a/singlecp/deploy_aelf.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -dir=`pwd` -ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` -sudo sed -i "s/172.31.8.57/$ip/g" appsettings.json -sudo docker pull aelf/node:testnet-v0.9.2 -sudo docker run -itd --name aelf-node-test -v $dir:/opt/node -v $dir/keys:/root/.local/share/aelf/keys -p 8001:8000 -p 6800:6800 -w /opt/node aelf/node:testnet-v0.9.2 dotnet /app/AElf.Launcher.dll -sleep 30 -height=`curl -s http://$ip:8001/api/blockChain/blockHeight` -echo "height is $height" From b79e582242d3714bf8c6f4c14e81c05e730ef2e6 Mon Sep 17 00:00:00 2001 From: "levi.xiang" Date: Wed, 11 Mar 2020 15:40:36 +0800 Subject: [PATCH 11/70] remove nouse field --- AElf.Client/Dto/TransactionResultDto.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/AElf.Client/Dto/TransactionResultDto.cs b/AElf.Client/Dto/TransactionResultDto.cs index 0321ea9..7f0cdfd 100644 --- a/AElf.Client/Dto/TransactionResultDto.cs +++ b/AElf.Client/Dto/TransactionResultDto.cs @@ -17,11 +17,7 @@ public class TransactionResultDto public TransactionDto Transaction { get; set; } public string ReturnValue { get; set; } - - public string ReadableReturnValue { get; set; } - - public string Error { get; set; } - public TransactionFeeDto TransactionFee { get; set; } + public string Error { get; set; } } } \ No newline at end of file From f2fa798e2132a739779a5427ead25562956851f5 Mon Sep 17 00:00:00 2001 From: "levi.xiang" Date: Thu, 12 Mar 2020 20:15:05 +0800 Subject: [PATCH 12/70] adjust txResultDto --- AElf.Client.Test/ClientTest.cs | 60 ++++++++++++++++++- .../TransactionResultDtoExtension.cs | 46 ++++++++++++++ AElf.Client/Protobuf/Proto/options.proto | 38 ++++++++++++ .../Protobuf/Proto/token_contract.proto | 7 +++ .../Protobuf/Proto/transaction_fee.proto | 41 +++++++++++++ 5 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 AElf.Client/Extension/TransactionResultDtoExtension.cs create mode 100644 AElf.Client/Protobuf/Proto/options.proto create mode 100644 AElf.Client/Protobuf/Proto/transaction_fee.proto diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 781a4a4..5c050e5 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -5,6 +5,8 @@ using AElf.Cryptography; using AElf.Types; using AElf.Client.Dto; +using AElf.Client.Extension; +using AElf.Client.MultiToken; using AElf.Client.Service; using Google.Protobuf; using Newtonsoft.Json; @@ -30,7 +32,7 @@ public class ClientTest // Address and privateKey of a node. private readonly string _address; - private const string PrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; + private const string PrivateKey = "cd86ab6347d8e52bbbe8532141fc59ce596268143a308d1d40fedf385528b458"; private AElfClient Client { get; } private readonly ITestOutputHelper _testOutputHelper; @@ -435,6 +437,62 @@ public void GetNewKeyPairInfo_Test() _testOutputHelper.WriteLine(addressOutput); } + [Fact] + public async Task GetAccountBalance_Test() + { + var tokenAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); + var methodName = "GetBalance"; + var param = new GetBalanceInput + { + Symbol = "ELF", + Owner = new Proto.Address {Value = AddressHelper.Base58StringToAddress(_address).Value} + }; + + var transaction = + await Client.GenerateTransaction(_address, tokenAddress.GetFormatted(), methodName, param); + var txWithSign = Client.SignTransaction(PrivateKey, transaction); + + var transactionResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto + { + RawTransaction = txWithSign.ToByteArray().ToHex() + }); + Assert.True(transactionResult != null); + + var balance = GetBalanceOutput.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionResult)); + _testOutputHelper.WriteLine($"Balance of {_address} = {balance.Balance} {balance.Symbol}"); + } + + [Fact(Skip = "Redo this later.")] + public async Task GetTransactionFee_Test() + { + var toAccount = "2DyzHMD1DqurK9hhiPa91mTBEtcPNrPvY5Uh7tnqRMXGnB381R"; + var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); + var methodName = "TransferFrom"; + var param = new TransferFromInput + { + From = new Proto.Address {Value = AddressHelper.Base58StringToAddress(_address).Value}, + To = new Proto.Address {Value = AddressHelper.Base58StringToAddress(toAccount).Value}, + Symbol = "ELF", + Amount = 10000 + }; + + var transaction = await Client.GenerateTransaction(_address, toAddress.GetFormatted(), methodName, param); + var txWithSign = Client.SignTransaction(PrivateKey, transaction); + + var result = await Client.SendTransactionAsync(new SendTransactionInput + { + RawTransaction = txWithSign.ToByteArray().ToHex() + }); + + result.ShouldNotBeNull(); + _testOutputHelper.WriteLine(result.TransactionId); + + await Task.Delay(2000); + var transactionResult = await Client.GetTransactionResultAsync(result.TransactionId); + var res = transactionResult.GetAllTokensFee(); + _testOutputHelper.WriteLine(JsonConvert.SerializeObject(res, Formatting.Indented)); + } + #endregion #region private methods diff --git a/AElf.Client/Extension/TransactionResultDtoExtension.cs b/AElf.Client/Extension/TransactionResultDtoExtension.cs new file mode 100644 index 0000000..8c2fca4 --- /dev/null +++ b/AElf.Client/Extension/TransactionResultDtoExtension.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using AElf.Client.Dto; +using AElf.Client.MultiToken; +using Google.Protobuf; + +namespace AElf.Client.Extension +{ + public static class TransactionResultDtoExtension + { + public static long GetDefaultTokenFee(this TransactionResultDto transactionResultDto) + { + var eventLogs = transactionResultDto.Logs; + if (eventLogs == null) + { + return 0; + } + foreach (var log in eventLogs) + { + if (log.Name == nameof(TransactionFeeCharged)) + { + var info = TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(log.NonIndexed)); + return info.Amount; + } + } + + return 0; + } + + public static Dictionary GetAllTokensFee(this TransactionResultDto transactionResultDto) + { + var dic = new Dictionary(); + var eventLogs = transactionResultDto.Logs; + if (eventLogs == null) return dic; + foreach (var log in eventLogs) + { + if (log.Name == nameof(ResourceTokenCharged) || log.Name == nameof(TransactionFeeCharged)) + { + var info = TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(log.NonIndexed)); + dic.Add(info.Symbol, info.Amount); + } + } + + return dic; + } + } +} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/options.proto b/AElf.Client/Protobuf/Proto/options.proto new file mode 100644 index 0000000..b16a05a --- /dev/null +++ b/AElf.Client/Protobuf/Proto/options.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package client; + +import "google/protobuf/descriptor.proto"; + +option csharp_namespace = "AElf.Client"; + +// All aelf custom options field numbers are like 50yxxx +// where y stands for the custom options type: +// 0 - FileOptions +// 1 - MessageOptions +// 2 - FieldOptions +// 3 - EnumOptions +// 4 - EnumValueOptions +// 5 - ServiceOptions +// 6 - MethodOptions + +extend google.protobuf.FileOptions { + string identity = 500001; +} + +extend google.protobuf.ServiceOptions { + repeated string base = 505001; + string csharp_state = 505030; +} + +extend google.protobuf.MethodOptions { + bool is_view = 506001; +} + +extend google.protobuf.MessageOptions { + bool is_event = 50100; +} + +extend google.protobuf.FieldOptions { + bool is_indexed = 502001; +} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/token_contract.proto b/AElf.Client/Protobuf/Proto/token_contract.proto index d696c1f..d597da1 100644 --- a/AElf.Client/Protobuf/Proto/token_contract.proto +++ b/AElf.Client/Protobuf/Proto/token_contract.proto @@ -83,4 +83,11 @@ message GetCrossChainTransferTokenContractAddressInput { int32 chainId = 1; } +message TransferFromInput { + client.Address from = 1; + client.Address to = 2; + string symbol = 3; + sint64 amount = 4; + string memo = 5; +} diff --git a/AElf.Client/Protobuf/Proto/transaction_fee.proto b/AElf.Client/Protobuf/Proto/transaction_fee.proto new file mode 100644 index 0000000..023f315 --- /dev/null +++ b/AElf.Client/Protobuf/Proto/transaction_fee.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; + +package client; + +import "options.proto"; + +option csharp_namespace = "AElf.Client.MultiToken"; + +// Messages + +message TransactionSizeFeeSymbols +{ + repeated TransactionSizeFeeSymbol transaction_size_fee_symbol_list = 1; +} + +message TransactionSizeFeeSymbol +{ + string token_symbol = 1; + sint32 base_token_weight = 2; + sint32 added_token_weight = 3; +} + +// Events + +message TransactionFeeCharged { + option (client.is_event) = true; + string symbol = 1; + sint64 amount = 2; +} + +message ResourceTokenCharged { + option (client.is_event) = true; + string symbol = 1; + sint64 amount = 2; +} + +message ResourceTokenOwned { + option (client.is_event) = true; + string symbol = 1; + sint64 amount = 2; +} \ No newline at end of file From 1642a75151e9f5d112696a3e738ba67364189a69 Mon Sep 17 00:00:00 2001 From: "levi.xiang" Date: Thu, 12 Mar 2020 20:18:35 +0800 Subject: [PATCH 13/70] fix build problem --- AElf.Client/AElf.Client.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AElf.Client/AElf.Client.csproj b/AElf.Client/AElf.Client.csproj index 18ffa2d..b527806 100644 --- a/AElf.Client/AElf.Client.csproj +++ b/AElf.Client/AElf.Client.csproj @@ -25,7 +25,7 @@ - + none PreserveNewest ./Protobuf/Generated From 86e6077f8524e65d4119f5fcc1c5aaa7b046e4f5 Mon Sep 17 00:00:00 2001 From: "levi.xiang" Date: Thu, 12 Mar 2020 20:21:27 +0800 Subject: [PATCH 14/70] remove TransactionFeeDto --- AElf.Client/Dto/TransactionFeeDto.cs | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 AElf.Client/Dto/TransactionFeeDto.cs diff --git a/AElf.Client/Dto/TransactionFeeDto.cs b/AElf.Client/Dto/TransactionFeeDto.cs deleted file mode 100644 index 27c22a1..0000000 --- a/AElf.Client/Dto/TransactionFeeDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace AElf.Client.Dto -{ - public class TransactionFeeDto - { - public Dictionary Value { get; set; } - } -} \ No newline at end of file From 2529757e7c1bcf103f106d221504626e3ad07742 Mon Sep 17 00:00:00 2001 From: "levi.xiang" Date: Sat, 14 Mar 2020 10:52:46 +0800 Subject: [PATCH 15/70] improve SendTransactionsAsync_Test --- AElf.Client.Test/ClientTest.cs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 5c050e5..6a08071 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Text; using System.Threading.Tasks; using AElf.Cryptography; using AElf.Types; @@ -261,6 +262,7 @@ public async Task ExecuteRawTransactionAsync_Test() (await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Consensus"))) .GetFormatted(); + _testOutputHelper.WriteLine(rawTransactionResult); Assert.True(rawTransactionResult == $"\"{consensusAddress}\""); } @@ -330,30 +332,23 @@ public async Task SendTransactionsAsync_Test() var param2 = Hash.FromString("AElf.ContractNames.Vote"); var parameters = new List {param1, param2}; - var transactions = new List(); + var sb = new StringBuilder(); foreach (var param in parameters) { var tx = await Client.GenerateTransaction(_address, toAddress, methodName, param); var txWithSign = Client.SignTransaction(PrivateKey, tx); - - transactions.Add(txWithSign); + sb.Append(txWithSign.ToByteArray().ToHex() + ','); } - var result1 = await Client.SendTransactionAsync(new SendTransactionInput + var result1 = await Client.SendTransactionsAsync(new SendTransactionsInput { - RawTransaction = transactions[0].ToByteArray().ToHex() + RawTransactions = sb.ToString().Substring(0, sb.Length - 1) }); Assert.True(result1 != null); + _testOutputHelper.WriteLine(JsonConvert.SerializeObject(result1)); - var result2 = await Client.SendTransactionAsync(new SendTransactionInput - { - RawTransaction = transactions[1].ToByteArray().ToHex() - }); - - Assert.True(result2 != null); - _testOutputHelper.WriteLine(result1.TransactionId + "\r\n" + result2.TransactionId); } [Fact] From b73b9fa4685a49df0a2fe6c9fcc64af156345443 Mon Sep 17 00:00:00 2001 From: "levi.xiang" Date: Sat, 14 Mar 2020 16:39:02 +0800 Subject: [PATCH 16/70] rename GetTransactionFees --- AElf.Client.Test/ClientTest.cs | 4 +-- .../TransactionResultDtoExtension.cs | 29 ++++--------------- 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 6a08071..3430b92 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -33,7 +33,7 @@ public class ClientTest // Address and privateKey of a node. private readonly string _address; - private const string PrivateKey = "cd86ab6347d8e52bbbe8532141fc59ce596268143a308d1d40fedf385528b458"; + private const string PrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; private AElfClient Client { get; } private readonly ITestOutputHelper _testOutputHelper; @@ -484,7 +484,7 @@ public async Task GetTransactionFee_Test() await Task.Delay(2000); var transactionResult = await Client.GetTransactionResultAsync(result.TransactionId); - var res = transactionResult.GetAllTokensFee(); + var res = transactionResult.GetTransactionFees(); _testOutputHelper.WriteLine(JsonConvert.SerializeObject(res, Formatting.Indented)); } diff --git a/AElf.Client/Extension/TransactionResultDtoExtension.cs b/AElf.Client/Extension/TransactionResultDtoExtension.cs index 8c2fca4..201b294 100644 --- a/AElf.Client/Extension/TransactionResultDtoExtension.cs +++ b/AElf.Client/Extension/TransactionResultDtoExtension.cs @@ -7,40 +7,21 @@ namespace AElf.Client.Extension { public static class TransactionResultDtoExtension { - public static long GetDefaultTokenFee(this TransactionResultDto transactionResultDto) + public static Dictionary GetTransactionFees(this TransactionResultDto transactionResultDto) { + var transactionFeesDict = new Dictionary(); var eventLogs = transactionResultDto.Logs; - if (eventLogs == null) - { - return 0; - } - foreach (var log in eventLogs) - { - if (log.Name == nameof(TransactionFeeCharged)) - { - var info = TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(log.NonIndexed)); - return info.Amount; - } - } - - return 0; - } - - public static Dictionary GetAllTokensFee(this TransactionResultDto transactionResultDto) - { - var dic = new Dictionary(); - var eventLogs = transactionResultDto.Logs; - if (eventLogs == null) return dic; + if (eventLogs == null) return transactionFeesDict; foreach (var log in eventLogs) { if (log.Name == nameof(ResourceTokenCharged) || log.Name == nameof(TransactionFeeCharged)) { var info = TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(log.NonIndexed)); - dic.Add(info.Symbol, info.Amount); + transactionFeesDict.Add(info.Symbol, info.Amount); } } - return dic; + return transactionFeesDict; } } } \ No newline at end of file From dcf9966e85d2aec787b757af11ecf9ee55205264 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Tue, 17 Mar 2020 10:27:03 +0800 Subject: [PATCH 17/70] fix method GetTransactionFees --- AElf.Client.Test/ClientTest.cs | 21 +++++++++++-------- .../TransactionResultDtoExtension.cs | 16 ++++++-------- .../Protobuf/Proto/token_contract.proto | 6 ++++++ 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 3430b92..5bbb6e7 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -33,7 +33,7 @@ public class ClientTest // Address and privateKey of a node. private readonly string _address; - private const string PrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; + private const string PrivateKey = "85447a83ce2ed09a4a2424304e54f9e3dbf5f2c1d28a4554447f868a6ff3565a"; private AElfClient Client { get; } private readonly ITestOutputHelper _testOutputHelper; @@ -457,18 +457,17 @@ public async Task GetAccountBalance_Test() _testOutputHelper.WriteLine($"Balance of {_address} = {balance.Balance} {balance.Symbol}"); } - [Fact(Skip = "Redo this later.")] + [Fact] public async Task GetTransactionFee_Test() { var toAccount = "2DyzHMD1DqurK9hhiPa91mTBEtcPNrPvY5Uh7tnqRMXGnB381R"; var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); - var methodName = "TransferFrom"; - var param = new TransferFromInput + var methodName = "Transfer"; + var param = new TransferInput { - From = new Proto.Address {Value = AddressHelper.Base58StringToAddress(_address).Value}, To = new Proto.Address {Value = AddressHelper.Base58StringToAddress(toAccount).Value}, Symbol = "ELF", - Amount = 10000 + Amount = 1000 }; var transaction = await Client.GenerateTransaction(_address, toAddress.GetFormatted(), methodName, param); @@ -482,10 +481,14 @@ public async Task GetTransactionFee_Test() result.ShouldNotBeNull(); _testOutputHelper.WriteLine(result.TransactionId); - await Task.Delay(2000); + await Task.Delay(4000); var transactionResult = await Client.GetTransactionResultAsync(result.TransactionId); - var res = transactionResult.GetTransactionFees(); - _testOutputHelper.WriteLine(JsonConvert.SerializeObject(res, Formatting.Indented)); + transactionResult.Status.ShouldBe(TransactionResultStatus.Mined.ToString().ToUpper()); + var transactionFees = transactionResult.GetTransactionFees(); + transactionFees.Count.ShouldBe(1); + transactionFees.First().Key.ShouldBe("ELF"); + transactionFees.First().Value.ShouldBe(25760000L); + _testOutputHelper.WriteLine(JsonConvert.SerializeObject(transactionFees, Formatting.Indented)); } #endregion diff --git a/AElf.Client/Extension/TransactionResultDtoExtension.cs b/AElf.Client/Extension/TransactionResultDtoExtension.cs index 201b294..55a2978 100644 --- a/AElf.Client/Extension/TransactionResultDtoExtension.cs +++ b/AElf.Client/Extension/TransactionResultDtoExtension.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using AElf.Client.Dto; using AElf.Client.MultiToken; using Google.Protobuf; @@ -9,19 +10,14 @@ public static class TransactionResultDtoExtension { public static Dictionary GetTransactionFees(this TransactionResultDto transactionResultDto) { - var transactionFeesDict = new Dictionary(); - var eventLogs = transactionResultDto.Logs; - if (eventLogs == null) return transactionFeesDict; - foreach (var log in eventLogs) + var relatedLogs = transactionResultDto.Logs?.Where(l => l.Name == nameof(TransactionFeeCharged)).ToList(); + if (relatedLogs == null || !relatedLogs.Any()) { - if (log.Name == nameof(ResourceTokenCharged) || log.Name == nameof(TransactionFeeCharged)) - { - var info = TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(log.NonIndexed)); - transactionFeesDict.Add(info.Symbol, info.Amount); - } + return new Dictionary(); } - return transactionFeesDict; + return relatedLogs.Select(l => TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(l.NonIndexed))) + .ToDictionary(e => e.Symbol, e => e.Amount); } } } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/token_contract.proto b/AElf.Client/Protobuf/Proto/token_contract.proto index d597da1..511e914 100644 --- a/AElf.Client/Protobuf/Proto/token_contract.proto +++ b/AElf.Client/Protobuf/Proto/token_contract.proto @@ -91,3 +91,9 @@ message TransferFromInput { string memo = 5; } +message TransferInput { + client.Address to = 1; + string symbol = 2; + sint64 amount = 3; + string memo = 4; +} From 2edb8d5ff2e61ca81f01ff0faac24d230a90bd70 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Thu, 19 Mar 2020 13:05:36 +0800 Subject: [PATCH 18/70] use GenerateKeyPairInfo --- AElf.Client.Test/ClientTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 5bbb6e7..b7fef84 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -460,7 +460,7 @@ public async Task GetAccountBalance_Test() [Fact] public async Task GetTransactionFee_Test() { - var toAccount = "2DyzHMD1DqurK9hhiPa91mTBEtcPNrPvY5Uh7tnqRMXGnB381R"; + var toAccount = Client.GenerateKeyPairInfo().Address; var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); var methodName = "Transfer"; var param = new TransferInput From 317257b8909895aac5c374bfa9ec4868de48569f Mon Sep 17 00:00:00 2001 From: zhxymh Date: Thu, 19 Mar 2020 15:54:35 +0800 Subject: [PATCH 19/70] modify GetTransactionFees --- AElf.Client.Test/ClientTest.cs | 31 +++++++++++++++++-- .../TransactionResultDtoExtension.cs | 27 +++++++++++++--- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index b7fef84..0424e65 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -458,7 +459,7 @@ public async Task GetAccountBalance_Test() } [Fact] - public async Task GetTransactionFee_Test() + public async Task TransactionFee_Test() { var toAccount = Client.GenerateKeyPairInfo().Address; var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); @@ -483,14 +484,38 @@ public async Task GetTransactionFee_Test() await Task.Delay(4000); var transactionResult = await Client.GetTransactionResultAsync(result.TransactionId); - transactionResult.Status.ShouldBe(TransactionResultStatus.Mined.ToString().ToUpper()); var transactionFees = transactionResult.GetTransactionFees(); - transactionFees.Count.ShouldBe(1); transactionFees.First().Key.ShouldBe("ELF"); transactionFees.First().Value.ShouldBe(25760000L); _testOutputHelper.WriteLine(JsonConvert.SerializeObject(transactionFees, Formatting.Indented)); } + [Fact] + public async Task GetTransactionFee_Test() + { + var transactionResultDto = new TransactionResultDto + { + Logs = new[] + { + new LogEventDto + { + Name = "TransactionFeeCharged", + NonIndexed = Convert.ToBase64String((new TransactionFeeCharged {Symbol = "ELF", Amount = 1000}).ToByteArray()) + }, + new LogEventDto + { + Name = "ResourceTokenCharged", + NonIndexed = Convert.ToBase64String((new ResourceTokenCharged {Symbol = "READ", Amount = 800}).ToByteArray()) + } + } + }; + + var transactionFees = transactionResultDto.GetTransactionFees(); + transactionFees.Count.ShouldBe(2); + transactionFees["ELF"].ShouldBe(1000); + transactionFees["READ"].ShouldBe(800); + } + #endregion #region private methods diff --git a/AElf.Client/Extension/TransactionResultDtoExtension.cs b/AElf.Client/Extension/TransactionResultDtoExtension.cs index 55a2978..4dd8bdd 100644 --- a/AElf.Client/Extension/TransactionResultDtoExtension.cs +++ b/AElf.Client/Extension/TransactionResultDtoExtension.cs @@ -10,14 +10,31 @@ public static class TransactionResultDtoExtension { public static Dictionary GetTransactionFees(this TransactionResultDto transactionResultDto) { - var relatedLogs = transactionResultDto.Logs?.Where(l => l.Name == nameof(TransactionFeeCharged)).ToList(); - if (relatedLogs == null || !relatedLogs.Any()) + var result = new Dictionary(); + + var transactionFeeLogs = + transactionResultDto.Logs?.Where(l => l.Name == nameof(TransactionFeeCharged)).ToList(); + if (transactionFeeLogs != null) + { + foreach (var transactionFee in transactionFeeLogs.Select(transactionFeeLog => + TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) + { + result.Add(transactionFee.Symbol, transactionFee.Amount); + } + } + + var resourceTokenLogs = + transactionResultDto.Logs?.Where(l => l.Name == nameof(ResourceTokenCharged)).ToList(); + if (resourceTokenLogs != null) { - return new Dictionary(); + foreach (var resourceToken in resourceTokenLogs.Select(transactionFeeLog => + ResourceTokenCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) + { + result.Add(resourceToken.Symbol, resourceToken.Amount); + } } - return relatedLogs.Select(l => TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(l.NonIndexed))) - .ToDictionary(e => e.Symbol, e => e.Amount); + return result; } } } \ No newline at end of file From 5822ea1275bd7b7422264b9977d6c4b293431237 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Thu, 19 Mar 2020 16:01:21 +0800 Subject: [PATCH 20/70] improve test --- AElf.Client.Test/ClientTest.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 0424e65..db3ec2f 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -506,14 +506,25 @@ public async Task GetTransactionFee_Test() { Name = "ResourceTokenCharged", NonIndexed = Convert.ToBase64String((new ResourceTokenCharged {Symbol = "READ", Amount = 800}).ToByteArray()) + }, + new LogEventDto + { + Name = "ResourceTokenCharged", + NonIndexed = Convert.ToBase64String((new ResourceTokenCharged {Symbol = "WRITE", Amount = 600}).ToByteArray()) + }, + new LogEventDto + { + Name = "ResourceTokenOwned", + NonIndexed = Convert.ToBase64String((new ResourceTokenOwned {Symbol = "READ", Amount = 200}).ToByteArray()) } } }; var transactionFees = transactionResultDto.GetTransactionFees(); - transactionFees.Count.ShouldBe(2); + transactionFees.Count.ShouldBe(3); transactionFees["ELF"].ShouldBe(1000); transactionFees["READ"].ShouldBe(800); + transactionFees["WRITE"].ShouldBe(600); } #endregion From 797a3fd8447a082bfbe5d9688aa06a610c77ed54 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Thu, 19 Mar 2020 17:46:24 +0800 Subject: [PATCH 21/70] fix build error --- AElf.Client/AElf.Client.csproj | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/AElf.Client/AElf.Client.csproj b/AElf.Client/AElf.Client.csproj index b527806..9510e3a 100644 --- a/AElf.Client/AElf.Client.csproj +++ b/AElf.Client/AElf.Client.csproj @@ -21,11 +21,7 @@ - - - - - + none PreserveNewest ./Protobuf/Generated From 59fe4590da68af0b4c96a4a974846952d40c4274 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Thu, 19 Mar 2020 18:26:36 +0800 Subject: [PATCH 22/70] change private key --- AElf.Client.Test/ClientTest.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index db3ec2f..4e7af69 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -34,7 +34,7 @@ public class ClientTest // Address and privateKey of a node. private readonly string _address; - private const string PrivateKey = "85447a83ce2ed09a4a2424304e54f9e3dbf5f2c1d28a4554447f868a6ff3565a"; + private const string PrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; private AElfClient Client { get; } private readonly ITestOutputHelper _testOutputHelper; @@ -461,6 +461,7 @@ public async Task GetAccountBalance_Test() [Fact] public async Task TransactionFee_Test() { + var key = Client.GenerateKeyPairInfo(); var toAccount = Client.GenerateKeyPairInfo().Address; var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); var methodName = "Transfer"; @@ -471,8 +472,8 @@ public async Task TransactionFee_Test() Amount = 1000 }; - var transaction = await Client.GenerateTransaction(_address, toAddress.GetFormatted(), methodName, param); - var txWithSign = Client.SignTransaction(PrivateKey, transaction); + var transaction = await Client.GenerateTransaction(key.Address, toAddress.GetFormatted(), methodName, param); + var txWithSign = Client.SignTransaction(key.PrivateKey, transaction); var result = await Client.SendTransactionAsync(new SendTransactionInput { From 9979b30500958b2beb1c6b8ff81cee04f1889c1e Mon Sep 17 00:00:00 2001 From: zhxymh Date: Thu, 19 Mar 2020 18:44:11 +0800 Subject: [PATCH 23/70] fix test --- AElf.Client.Test/ClientTest.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 4e7af69..43c048c 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -461,7 +461,6 @@ public async Task GetAccountBalance_Test() [Fact] public async Task TransactionFee_Test() { - var key = Client.GenerateKeyPairInfo(); var toAccount = Client.GenerateKeyPairInfo().Address; var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); var methodName = "Transfer"; @@ -472,8 +471,8 @@ public async Task TransactionFee_Test() Amount = 1000 }; - var transaction = await Client.GenerateTransaction(key.Address, toAddress.GetFormatted(), methodName, param); - var txWithSign = Client.SignTransaction(key.PrivateKey, transaction); + var transaction = await Client.GenerateTransaction(_address, toAddress.GetFormatted(), methodName, param); + var txWithSign = Client.SignTransaction(PrivateKey, transaction); var result = await Client.SendTransactionAsync(new SendTransactionInput { From ad3216a7b4bbdba8a5580d8a78fcc571e993744b Mon Sep 17 00:00:00 2001 From: wudameinv <53204268+wudameinv@users.noreply.github.com> Date: Sat, 21 Mar 2020 13:52:54 +0800 Subject: [PATCH 24/70] Set up CI with Azure Pipelines [skip ci] --- azure-pipelines-1.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 azure-pipelines-1.yml diff --git a/azure-pipelines-1.yml b/azure-pipelines-1.yml new file mode 100644 index 0000000..1ceaac1 --- /dev/null +++ b/azure-pipelines-1.yml @@ -0,0 +1,19 @@ +jobs: +# All tasks on Linux +- job: build_all_linux + displayName: Build all tasks (Linux) + services: + redis: + image: redis + ports: + - 6379:6379 + pool: + vmImage: ubuntu-16.04 + steps: + - task: DotNetCoreInstaller@0 + inputs: + version: '3.1.101' + - script: cd scripts/aelf-node && bash start.sh + displayName: 'Deploy a full node' + - script: bash build.sh -target=test + displayName: 'build and test' \ No newline at end of file From 5613987fcbd0c177516fd4c16e2faadcab99b043 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Sat, 21 Mar 2020 14:14:17 +0800 Subject: [PATCH 25/70] improve test --- AElf.Client.Test/ClientTest.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 43c048c..b68d47f 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -525,6 +525,11 @@ public async Task GetTransactionFee_Test() transactionFees["ELF"].ShouldBe(1000); transactionFees["READ"].ShouldBe(800); transactionFees["WRITE"].ShouldBe(600); + + + transactionResultDto = new TransactionResultDto(); + transactionFees = transactionResultDto.GetTransactionFees(); + transactionFees.Count.ShouldBe(0); } #endregion From 206a0c2dd75f9e6b8078c102d5d17035e8aee658 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Sat, 21 Mar 2020 20:16:31 +0800 Subject: [PATCH 26/70] improve test --- AElf.Client.Test/ClientTest.cs | 150 +++++++++++++++++---------------- AElf.Client.Test/Extensions.cs | 43 ++++++++++ 2 files changed, 120 insertions(+), 73 deletions(-) create mode 100644 AElf.Client.Test/Extensions.cs diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index b68d47f..bdb3f91 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -34,7 +34,7 @@ public class ClientTest // Address and privateKey of a node. private readonly string _address; - private const string PrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; + private const string PrivateKey = "cd86ab6347d8e52bbbe8532141fc59ce596268143a308d1d40fedf385528b458"; private AElfClient Client { get; } private readonly ITestOutputHelper _testOutputHelper; @@ -54,18 +54,25 @@ public ClientTest(ITestOutputHelper testOutputHelper) public async Task GetBlockHeightTest() { var height = await Client.GetBlockHeightAsync(); - height.ShouldNotBeNull(); + height.ShouldBeGreaterThanOrEqualTo(1); _testOutputHelper.WriteLine(height.ToString()); } [Fact] - public async Task GetBlock_ByHeightAsyncTest() + public async Task GetBlock_Test() { var height = await Client.GetBlockHeightAsync(); - var blockDto = await Client.GetBlockByHeightAsync(height); - Assert.True(blockDto != null); - - var block = JsonConvert.SerializeObject(blockDto, Formatting.Indented); + var blockByHeight = await Client.GetBlockByHeightAsync(height); + var blockByHash = await Client.GetBlockByHashAsync(blockByHeight.BlockHash); + + var blockByHeightSerialized =JsonConvert.SerializeObject(blockByHeight, Formatting.Indented); + var blockByHashSerialized =JsonConvert.SerializeObject(blockByHash, Formatting.Indented); + + blockByHeightSerialized.ShouldBe(blockByHashSerialized); + blockByHeight.Header.Height.ShouldBe(height); + blockByHeight.IsComplete().ShouldBeTrue(); + + var block = JsonConvert.SerializeObject(blockByHeight, Formatting.Indented); _testOutputHelper.WriteLine(block); } @@ -84,29 +91,28 @@ public async Task GetBlockByHeight_Failed_Test() _testOutputHelper.WriteLine(str); } - [Fact] - public async Task GetBlockAsync_Success_Test() - { - var chainStatusDto = await Client.GetChainStatusAsync(); - var genesisHash = chainStatusDto.GenesisBlockHash; - - var blockDto = await Client.GetBlockByHashAsync(genesisHash, true); - Assert.True(blockDto != null); - - var block = JsonConvert.SerializeObject(blockDto, Formatting.Indented); - _testOutputHelper.WriteLine(block); - } - #endregion #region chain [Fact] - public async Task GetChainStatusAsync_Test() + public async Task GetChainStatus_Test() { var chainStatusDto = await Client.GetChainStatusAsync(); - Assert.True(chainStatusDto != null); - + + chainStatusDto.Branches.Count.ShouldBeGreaterThanOrEqualTo(1); + chainStatusDto.Branches.First().Key.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.Branches.First().Value.ShouldBeGreaterThanOrEqualTo(1); + chainStatusDto.ChainId.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.BestChainHash.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.BestChainHeight.ShouldBeGreaterThanOrEqualTo(1); + chainStatusDto.GenesisBlockHash.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.GenesisContractAddress.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.LongestChainHash.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.LongestChainHeight.ShouldBeGreaterThanOrEqualTo(1); + chainStatusDto.LastIrreversibleBlockHash.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.LastIrreversibleBlockHeight.ShouldBeGreaterThanOrEqualTo(1); + var chainStatus = JsonConvert.SerializeObject(chainStatusDto, Formatting.Indented); _testOutputHelper.WriteLine(chainStatus); } @@ -120,7 +126,7 @@ public async Task GetChainStatusAsync_Test() /// /// [Fact(Skip = "Redo this later.")] - public async Task AddPeerAsync_Test() + public async Task AddPeer_Test() { // add ipAddress var addressToAdd = "192.168.199.122:7003"; @@ -131,7 +137,7 @@ public async Task AddPeerAsync_Test() } [Fact(Skip = "Redo this later.")] - public async Task RemovePeerAsync_Test() + public async Task RemovePeer_Test() { var peers = await Client.GetPeersAsync(false); peers.ShouldNotBeEmpty(); @@ -143,7 +149,7 @@ public async Task RemovePeerAsync_Test() } [Fact] - public async Task GetPeersAsync_Test() + public async Task GetPeers_Test() { var peers = await Client.GetPeersAsync(false); Assert.True(peers != null); @@ -152,7 +158,7 @@ public async Task GetPeersAsync_Test() } [Fact] - public async Task GetNetworkInfoAsync_Test() + public async Task GetNetworkInfo_Test() { var netWorkInfo = await Client.GetNetworkInfoAsync(); Assert.True(netWorkInfo != null); @@ -165,7 +171,7 @@ public async Task GetNetworkInfoAsync_Test() #region transaction [Fact] - public async Task GetTaskQueueStatusAsync_Test() + public async Task GetTaskQueueStatus_Test() { var taskQueueStatus = await Client.GetTaskQueueStatusAsync(); taskQueueStatus.ShouldNotBeEmpty(); @@ -175,7 +181,7 @@ public async Task GetTaskQueueStatusAsync_Test() } [Fact] - public async Task GetTransactionPoolStatusAsync_Test() + public async Task GetTransactionPoolStatus_Test() { var poolStatus = await Client.GetTransactionPoolStatusAsync(); Assert.True(poolStatus != null); @@ -185,7 +191,7 @@ public async Task GetTransactionPoolStatusAsync_Test() } [Fact] - public async Task ExecuteTransactionAsync_Test() + public async Task ExecuteTransaction_Test() { var toAddress = GenesisAddress; var methodName = ContractMethodName; @@ -206,7 +212,7 @@ public async Task ExecuteTransactionAsync_Test() } [Fact] - public async Task CreateRawTransactionAsync_Test() + public async Task CreateRawTransaction_Test() { var address = GenesisAddress; var status = await Client.GetChainStatusAsync(); @@ -230,7 +236,7 @@ public async Task CreateRawTransactionAsync_Test() } [Fact] - public async Task ExecuteRawTransactionAsync_Test() + public async Task ExecuteRawTransaction_Test() { var address = GenesisAddress; var status = await Client.GetChainStatusAsync(); @@ -263,12 +269,13 @@ public async Task ExecuteRawTransactionAsync_Test() (await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Consensus"))) .GetFormatted(); + var addressResult = Address.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(rawTransactionResult)); _testOutputHelper.WriteLine(rawTransactionResult); - Assert.True(rawTransactionResult == $"\"{consensusAddress}\""); + Assert.True(addressResult.GetFormatted() == consensusAddress); } [Fact] - public async Task SendRawTransactionAsync_Test() + public async Task SendRawTransaction_Test() { var toAddress = GenesisAddress; var status = await Client.GetChainStatusAsync(); @@ -299,14 +306,16 @@ public async Task SendRawTransactionAsync_Test() ReturnTransaction = true }); - Assert.True(rawTransactionResult != null); + rawTransactionResult.ShouldNotBeNull(); + rawTransactionResult.Transaction.ShouldNotBeNull(); + rawTransactionResult.TransactionId.ShouldNotBeNullOrWhiteSpace(); var result = JsonConvert.SerializeObject(rawTransactionResult, Formatting.Indented); _testOutputHelper.WriteLine(result); } [Fact] - public async Task SendTransactionAsync_Test() + public async Task SendTransaction_Test() { var toAddress = GenesisAddress; var methodName = ContractMethodName; @@ -321,11 +330,12 @@ public async Task SendTransactionAsync_Test() }); result.ShouldNotBeNull(); + result.TransactionId.ShouldNotBeNull(); _testOutputHelper.WriteLine(result.TransactionId); } [Fact] - public async Task SendTransactionsAsync_Test() + public async Task SendTransactions_Test() { var toAddress = GenesisAddress; var methodName = ContractMethodName; @@ -348,12 +358,13 @@ public async Task SendTransactionsAsync_Test() }); Assert.True(result1 != null); + result1.Length.ShouldBe(2); _testOutputHelper.WriteLine(JsonConvert.SerializeObject(result1)); } [Fact] - public async Task GetTransactionResultAsync_Test() + public async Task GetTransactionResult_Test() { var firstBlockDto = await Client.GetBlockByHeightAsync(1, true); var transactionId = firstBlockDto.Body.Transactions.FirstOrDefault(); @@ -363,7 +374,7 @@ public async Task GetTransactionResultAsync_Test() } [Fact] - public async Task GetTransactionResultsAsync_Test() + public async Task GetTransactionResults_Test() { var firstBlockDto = await Client.GetBlockByHeightAsync(1, true); var blockHash = firstBlockDto.BlockHash; @@ -376,7 +387,7 @@ public async Task GetTransactionResultsAsync_Test() } [Fact] - public async Task GetMerklePathByTransactionIdAsync_Test() + public async Task GetMerklePathByTransactionId_Test() { var firstBlockDto = await Client.GetBlockByHeightAsync(1, true); var transactionId = firstBlockDto.Body.Transactions.FirstOrDefault(); @@ -390,13 +401,10 @@ public async Task GetMerklePathByTransactionIdAsync_Test() } [Fact] - public async Task GetChainIdAsync_Test() + public async Task GetChainId_Test() { var chainId = await Client.GetChainIdAsync(); - chainId.ShouldNotBeNull(); - chainId.ShouldBeOfType(typeof(int)); - - _testOutputHelper.WriteLine(chainId.ToString()); + chainId.ShouldBe(9992731); } [Fact] @@ -407,7 +415,7 @@ public async Task IsConnected_Test() } [Fact] - public async Task GetGenesisContractAddressAsync_Test() + public async Task GetGenesisContractAddress_Test() { var genesisAddress = await Client.GetGenesisContractAddressAsync(); genesisAddress.ShouldNotBeEmpty(); @@ -434,32 +442,7 @@ public void GetNewKeyPairInfo_Test() } [Fact] - public async Task GetAccountBalance_Test() - { - var tokenAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); - var methodName = "GetBalance"; - var param = new GetBalanceInput - { - Symbol = "ELF", - Owner = new Proto.Address {Value = AddressHelper.Base58StringToAddress(_address).Value} - }; - - var transaction = - await Client.GenerateTransaction(_address, tokenAddress.GetFormatted(), methodName, param); - var txWithSign = Client.SignTransaction(PrivateKey, transaction); - - var transactionResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto - { - RawTransaction = txWithSign.ToByteArray().ToHex() - }); - Assert.True(transactionResult != null); - - var balance = GetBalanceOutput.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionResult)); - _testOutputHelper.WriteLine($"Balance of {_address} = {balance.Balance} {balance.Symbol}"); - } - - [Fact] - public async Task TransactionFee_Test() + public async Task Transfer_Test() { var toAccount = Client.GenerateKeyPairInfo().Address; var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); @@ -484,10 +467,31 @@ public async Task TransactionFee_Test() await Task.Delay(4000); var transactionResult = await Client.GetTransactionResultAsync(result.TransactionId); + transactionResult.Status.ShouldBe(TransactionResultStatus.Mined.ToString().ToUpper()); var transactionFees = transactionResult.GetTransactionFees(); transactionFees.First().Key.ShouldBe("ELF"); - transactionFees.First().Value.ShouldBe(25760000L); + transactionFees.First().Value.ShouldBeGreaterThan(0L); _testOutputHelper.WriteLine(JsonConvert.SerializeObject(transactionFees, Formatting.Indented)); + + var paramGetBalance = new GetBalanceInput + { + Symbol = "ELF", + Owner = new Proto.Address {Value = AddressHelper.Base58StringToAddress(toAccount).Value} + }; + + var transactionGetBalance = + await Client.GenerateTransaction(_address, toAddress.GetFormatted(), "GetBalance", paramGetBalance); + var txWithSignGetBalance = Client.SignTransaction(PrivateKey, transactionGetBalance); + + var transactionGetBalanceResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto + { + RawTransaction = txWithSignGetBalance.ToByteArray().ToHex() + }); + Assert.True(transactionResult != null); + + var balance = + GetBalanceOutput.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionGetBalanceResult)); + balance.Balance.ShouldBe(1000L); } [Fact] diff --git a/AElf.Client.Test/Extensions.cs b/AElf.Client.Test/Extensions.cs new file mode 100644 index 0000000..3d5b172 --- /dev/null +++ b/AElf.Client.Test/Extensions.cs @@ -0,0 +1,43 @@ +using System; +using AElf.Client.Dto; + +namespace AElf.Client.Test +{ + public static class Extensions + { + public static bool IsComplete(this BlockDto block) + { + if (block == null + || block.BlockHash.IsNullOrWhiteSpace() + || block.Header == null + || block.Header.Bloom.IsNullOrWhiteSpace() + || block.Header.Extra.IsNullOrWhiteSpace() + || block.Header.Height <= 0 + || block.Header.SignerPubkey.IsNullOrWhiteSpace() + || block.Header.ChainId.IsNullOrWhiteSpace() + || block.Header.PreviousBlockHash.IsNullOrWhiteSpace() + || block.Header.MerkleTreeRootOfTransactions.IsNullOrWhiteSpace() + || block.Header.MerkleTreeRootOfTransactionState.IsNullOrWhiteSpace() + || block.Header.MerkleTreeRootOfWorldState.IsNullOrWhiteSpace() + || block.Body == null + || block.Body.TransactionsCount == 0) + { + return false; + } + + return true; + } + + public static bool IsCompleteWithTransaction(this BlockDto block) + { + if (!block.IsComplete() + || block.Body.Transactions == null + || block.Body.Transactions.Count != block.Body.TransactionsCount) + { + return false; + } + + return true; + } + } +} \ No newline at end of file From cc7b6bee3bfca691ac9dfa7e2270e1e581a02567 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Tue, 14 Apr 2020 10:31:59 +0800 Subject: [PATCH 27/70] improve test --- AElf.Client.Test/ClientTest.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index bdb3f91..53cc87d 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -11,6 +11,7 @@ using AElf.Client.MultiToken; using AElf.Client.Service; using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Shouldly; @@ -193,11 +194,11 @@ public async Task GetTransactionPoolStatus_Test() [Fact] public async Task ExecuteTransaction_Test() { - var toAddress = GenesisAddress; - var methodName = ContractMethodName; - var param = Hash.FromString("AElf.ContractNames.TokenConverter"); + var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); + var methodName = "GetNativeTokenInfo"; + var param = new Empty(); - var transaction = await Client.GenerateTransaction(_address, toAddress, methodName, param); + var transaction = await Client.GenerateTransaction(_address, toAddress.GetFormatted(), methodName, param); var txWithSign = Client.SignTransaction(PrivateKey, transaction); var transactionResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto @@ -206,9 +207,8 @@ public async Task ExecuteTransaction_Test() }); Assert.True(transactionResult != null); - var addressResult = Address.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionResult)); - var address = await Client.GetContractAddressByName(param); - Assert.True(address == addressResult); + var tokenInfo = TokenInfo.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionResult)); + Assert.True(tokenInfo.Symbol == "ELF"); } [Fact] From 4e3832e464b55e507edfc6242c52e1f36e16ba3d Mon Sep 17 00:00:00 2001 From: wudameinv Date: Wed, 22 Apr 2020 12:24:36 +0000 Subject: [PATCH 28/70] update yml --- azure-pipelines.yml | 30 +++++++++++++++++++++++++++++- scripts/aelf-node/appsettings.json | 18 +++++------------- scripts/aelf-node/start-mac.sh | 10 ++++++++++ scripts/aelf-node/start-window.ps1 | 15 +++++++++++++++ scripts/aelf-node/start.sh | 15 +++++++++++---- 5 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 scripts/aelf-node/start-mac.sh create mode 100644 scripts/aelf-node/start-window.ps1 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index bc9ce8f..464e1d0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,4 +1,17 @@ jobs: +- job: build_all_window + displayName: Build all tasks (window) + pool: + vmImage: 'windows-2019' + variables: + phpVersion: 7.2 + steps: + - task: UseDotNet@2 + displayName: 'Install .NET Core SDK' + inputs: + version: 3.1.101 + - powershell: ./scripts/aelf-node/start-window.ps1 + displayName: 'Build and Test' # All tasks on Linux - job: build_all_linux displayName: Build all tasks (Linux) @@ -8,7 +21,7 @@ jobs: ports: - 6379:6379 pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 steps: - task: DotNetCoreInstaller@0 inputs: @@ -17,3 +30,18 @@ jobs: displayName: 'Deploy a full node' - script: bash build.sh -target=test displayName: 'build and test' +# All tasks on macOS +- job: build_all_macos + displayName: Build all tasks (macos) + pool: + vmImage: macos-latest + variables: + phpVersion: 7.2 + steps: + - task: DotNetCoreInstaller@0 + inputs: + version: '3.1.101' + - script: cd scripts/aelf-node && bash start-mac.sh + displayName: 'Deploy a full node' + - script: bash build.sh -target=test + displayName: 'build and test' diff --git a/scripts/aelf-node/appsettings.json b/scripts/aelf-node/appsettings.json index 4819e2c..082d14e 100644 --- a/scripts/aelf-node/appsettings.json +++ b/scripts/aelf-node/appsettings.json @@ -5,8 +5,8 @@ "AllowedHosts": "*", "CorsOrigins": "*", "ConnectionStrings": { - "BlockchainDb": "redis://172.31.8.57:6379", - "StateDb": "redis://172.31.8.57:6379" + "BlockchainDb": "redis://127.0.0.1:6379", + "StateDb": "redis://127.0.0.1:6379" }, "Account": { "NodeAccount": "SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM", @@ -22,7 +22,7 @@ "Kestrel": { "Endpoints": { "Http": { - "Url": "http://*:8000/" + "Url": "http://*:8001/" } } }, @@ -32,21 +32,13 @@ }, "Consensus": { "InitialMinerList": [ - ], + ], "MiningInterval": 4000, "StartTimestamp": "0", - "TimeEachTerm": 604800, + "PeriodSeconds": 604800, "MinerIncreaseInterval": 31536000 }, "Transaction": { "PoolLimit": 10240 - }, - "CrossChain": { - "Grpc": { - "ListeningPort": 5001 - } - }, - "Contract": { - "ContractDeploymentAuthorityRequired": "true" } } diff --git a/scripts/aelf-node/start-mac.sh b/scripts/aelf-node/start-mac.sh new file mode 100644 index 0000000..6625adb --- /dev/null +++ b/scripts/aelf-node/start-mac.sh @@ -0,0 +1,10 @@ +brew install redis +brew services start redis +brew install unzip +mkdir -p ~/.local/share/aelf/keys +cd ../../ +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview1/aelf.zip && unzip aelf.zip +cp scripts/aelf-node/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json ~/.local/share/aelf/keys/ +cp scripts/aelf-node/app* aelf/ +echo "start node" +cd aelf && dotnet AElf.Launcher.dll >/dev/null 2>&1 & diff --git a/scripts/aelf-node/start-window.ps1 b/scripts/aelf-node/start-window.ps1 new file mode 100644 index 0000000..6f23955 --- /dev/null +++ b/scripts/aelf-node/start-window.ps1 @@ -0,0 +1,15 @@ +wget https://github.com/microsoftarchive/redis/releases/download/win-3.2.100/Redis-x64-3.2.100.zip -OutFile redis.zip +Expand-Archive -Path redis.zip -DestinationPath redis ; +$job1 = Start-Job -ScriptBlock { cd D:\a\1\s\redis; .\redis-server.exe; } +sleep 30 +mkdir -p C:\Users\VssAdministrator\AppData\Local\aelf\keys +cp -r scripts\aelf-node\keys\* C:\Users\VssAdministrator\AppData\Local\aelf\keys; +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview1/aelf.zip -OutFile aelf.zip ; +Expand-Archive -Path aelf.zip -DestinationPath aelf ; +cp scripts\aelf-node\appsettings.json aelf\aelf\appsettings.json ; +cp scripts\aelf-node\appsettings.MainChain.TestNet.json aelf\aelf\appsettings.MainChain.TestNet.json ; +cd aelf/aelf +$job2 = Start-Job -ScriptBlock { cd D:\a\1\s\aelf\aelf; dotnet AElf.Launcher.dll; } +sleep 60 +cd D:\a\1\s +PowerShell.exe -file build.ps1 --target=test diff --git a/scripts/aelf-node/start.sh b/scripts/aelf-node/start.sh index 4ecb1ab..59903c7 100644 --- a/scripts/aelf-node/start.sh +++ b/scripts/aelf-node/start.sh @@ -1,9 +1,16 @@ #!/bin/bash -dir=`pwd` ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` -sudo sed -i "s/172.31.8.57/$ip/g" appsettings.json -sudo docker pull aelf/node:testnet-v0.9.2 -sudo docker run -itd --name aelf-node-test -v $dir:/opt/node -v $dir/keys:/root/.local/share/aelf/keys -p 8001:8000 -p 6800:6800 -w /opt/node aelf/node:testnet-v0.9.2 dotnet /app/AElf.Launcher.dll +sudo apt update && apt install unzip +sudo mkdir -p /home/ubuntu/.ssh/aelf/keys && sudo mkdir -p /root/.ssh/aelf/keys +cd ../../ +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview1/aelf.zip +sudo unzip aelf.zip +sed -i "s/127.0.0.1/$ip/g" scripts/aelf-node/appsettings.json +sudo mkdir -p aelf/aelf/keys +sudo cp scripts/aelf-node/keys/*.json aelf/aelf/keys/ +sudo cp scripts/aelf-node/app* aelf/ +echo "start node" +cd aelf && sudo dotnet AElf.Launcher.dll >/dev/null 2>&1 & sleep 30 height=`curl -s http://$ip:8001/api/blockChain/blockHeight` echo "height is $height" From e1c3c201743b3a644b51e3dc059471edbb29e5a7 Mon Sep 17 00:00:00 2001 From: wudameinv Date: Thu, 23 Apr 2020 05:45:39 +0000 Subject: [PATCH 29/70] add build.ps1 --- azure-pipelines-1.yml | 19 ------ build.ps1 | 154 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 19 deletions(-) delete mode 100644 azure-pipelines-1.yml create mode 100644 build.ps1 diff --git a/azure-pipelines-1.yml b/azure-pipelines-1.yml deleted file mode 100644 index 1ceaac1..0000000 --- a/azure-pipelines-1.yml +++ /dev/null @@ -1,19 +0,0 @@ -jobs: -# All tasks on Linux -- job: build_all_linux - displayName: Build all tasks (Linux) - services: - redis: - image: redis - ports: - - 6379:6379 - pool: - vmImage: ubuntu-16.04 - steps: - - task: DotNetCoreInstaller@0 - inputs: - version: '3.1.101' - - script: cd scripts/aelf-node && bash start.sh - displayName: 'Deploy a full node' - - script: bash build.sh -target=test - displayName: 'build and test' \ 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 From d859f92f98cbbaa199c610e2b27b96e4b9518d34 Mon Sep 17 00:00:00 2001 From: jinpeng wang Date: Thu, 7 May 2020 11:30:05 +0800 Subject: [PATCH 30/70] update packages --- AElf.Client.Test/AElf.Client.Test.csproj | 1 - AElf.Client.Test/ClientTest.cs | 44 ++++++++++---------- AElf.Client/AElf.Client.csproj | 8 ++-- AElf.Client/Dto/CreateRawTransactionInput.cs | 7 ++-- AElf.Client/Service/AElfClient.cs | 24 +++++------ 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/AElf.Client.Test/AElf.Client.Test.csproj b/AElf.Client.Test/AElf.Client.Test.csproj index a6d2091..116a214 100644 --- a/AElf.Client.Test/AElf.Client.Test.csproj +++ b/AElf.Client.Test/AElf.Client.Test.csproj @@ -6,7 +6,6 @@ - diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 53cc87d..f3601f6 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -194,11 +194,11 @@ public async Task GetTransactionPoolStatus_Test() [Fact] public async Task ExecuteTransaction_Test() { - var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); + var toAddress = await Client.GetContractAddressByName(HashHelper.ComputeFrom("AElf.ContractNames.Token")); var methodName = "GetNativeTokenInfo"; var param = new Empty(); - var transaction = await Client.GenerateTransaction(_address, toAddress.GetFormatted(), methodName, param); + var transaction = await Client.GenerateTransaction(_address, toAddress.ToBase58(), methodName, param); var txWithSign = Client.SignTransaction(PrivateKey, transaction); var transactionResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto @@ -226,7 +226,7 @@ public async Task CreateRawTransaction_Test() MethodName = ContractMethodName, Params = new JObject { - ["value"] = Hash.FromString("AElf.ContractNames.Token").Value.ToBase64() + ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Token").Value.ToBase64() }.ToString(), RefBlockNumber = height, RefBlockHash = blockHash @@ -250,13 +250,13 @@ public async Task ExecuteRawTransaction_Test() MethodName = ContractMethodName, Params = new JObject { - ["value"] = Hash.FromString("AElf.ContractNames.Consensus").Value.ToBase64() + ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Consensus").Value.ToBase64() }.ToString(), RefBlockNumber = height, RefBlockHash = blockHash }); - var transactionId = Hash.FromRawBytes(ByteArrayHelper.HexStringToByteArray(createRaw.RawTransaction)); + var transactionId = HashHelper.ComputeFrom(ByteArrayHelper.HexStringToByteArray(createRaw.RawTransaction)); var signature = GetSignatureWith(PrivateKey, transactionId.ToByteArray()).ToHex(); var rawTransactionResult = await Client.ExecuteRawTransactionAsync(new ExecuteRawTransactionDto { @@ -266,12 +266,12 @@ public async Task ExecuteRawTransaction_Test() rawTransactionResult.ShouldNotBeEmpty(); var consensusAddress = - (await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Consensus"))) - .GetFormatted(); + (await Client.GetContractAddressByName(HashHelper.ComputeFrom("AElf.ContractNames.Consensus"))) + .ToBase58(); - var addressResult = Address.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(rawTransactionResult)); + var addressResult = rawTransactionResult.Trim('"'); _testOutputHelper.WriteLine(rawTransactionResult); - Assert.True(addressResult.GetFormatted() == consensusAddress); + addressResult.ShouldBe(consensusAddress); } [Fact] @@ -289,14 +289,14 @@ public async Task SendRawTransaction_Test() MethodName = ContractMethodName, Params = new JObject { - ["value"] = Hash.FromString("AElf.ContractNames.Token").Value.ToBase64() + ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Token").Value.ToBase64() }.ToString(), RefBlockNumber = height, RefBlockHash = blockHash }); createRaw.RawTransaction.ShouldNotBeEmpty(); - var transactionId = Hash.FromRawBytes(ByteArrayHelper.HexStringToByteArray(createRaw.RawTransaction)); + var transactionId = HashHelper.ComputeFrom(ByteArrayHelper.HexStringToByteArray(createRaw.RawTransaction)); var signature = GetSignatureWith(PrivateKey, transactionId.ToByteArray()).ToHex(); var rawTransactionResult = await Client.SendRawTransactionAsync(new SendRawTransactionInput @@ -319,7 +319,7 @@ public async Task SendTransaction_Test() { var toAddress = GenesisAddress; var methodName = ContractMethodName; - var param = Hash.FromString("AElf.ContractNames.Vote"); + var param = HashHelper.ComputeFrom("AElf.ContractNames.Vote"); var transaction = await Client.GenerateTransaction(_address, toAddress, methodName, param); var txWithSign = Client.SignTransaction(PrivateKey, transaction); @@ -339,8 +339,8 @@ public async Task SendTransactions_Test() { var toAddress = GenesisAddress; var methodName = ContractMethodName; - var param1 = Hash.FromString("AElf.ContractNames.Token"); - var param2 = Hash.FromString("AElf.ContractNames.Vote"); + var param1 = HashHelper.ComputeFrom("AElf.ContractNames.Token"); + var param2 = HashHelper.ComputeFrom("AElf.ContractNames.Vote"); var parameters = new List {param1, param2}; var sb = new StringBuilder(); @@ -421,14 +421,14 @@ public async Task GetGenesisContractAddress_Test() genesisAddress.ShouldNotBeEmpty(); var address = await Client.GetContractAddressByName(Hash.Empty); - var genesisAddress2 = address.GetFormatted(); + var genesisAddress2 = address.ToBase58(); Assert.True(genesisAddress == genesisAddress2); } [Fact] public async Task GetFormattedAddress_Test() { - var result = await Client.GetFormattedAddress(AddressHelper.Base58StringToAddress(_address)); + var result = await Client.GetFormattedAddress(Address.FromBase58(_address)); _testOutputHelper.WriteLine(result); Assert.True(result == $"ELF_{_address}_AELF"); } @@ -445,16 +445,16 @@ public void GetNewKeyPairInfo_Test() public async Task Transfer_Test() { var toAccount = Client.GenerateKeyPairInfo().Address; - var toAddress = await Client.GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); + var toAddress = await Client.GetContractAddressByName(HashHelper.ComputeFrom("AElf.ContractNames.Token")); var methodName = "Transfer"; var param = new TransferInput { - To = new Proto.Address {Value = AddressHelper.Base58StringToAddress(toAccount).Value}, + To = new Proto.Address {Value = Address.FromBase58(toAccount).Value}, Symbol = "ELF", Amount = 1000 }; - var transaction = await Client.GenerateTransaction(_address, toAddress.GetFormatted(), methodName, param); + var transaction = await Client.GenerateTransaction(_address, toAddress.ToBase58(), methodName, param); var txWithSign = Client.SignTransaction(PrivateKey, transaction); var result = await Client.SendTransactionAsync(new SendTransactionInput @@ -476,11 +476,11 @@ public async Task Transfer_Test() var paramGetBalance = new GetBalanceInput { Symbol = "ELF", - Owner = new Proto.Address {Value = AddressHelper.Base58StringToAddress(toAccount).Value} + Owner = new Proto.Address {Value = Address.FromBase58(toAccount).Value} }; var transactionGetBalance = - await Client.GenerateTransaction(_address, toAddress.GetFormatted(), "GetBalance", paramGetBalance); + await Client.GenerateTransaction(_address, toAddress.ToBase58(), "GetBalance", paramGetBalance); var txWithSignGetBalance = Client.SignTransaction(PrivateKey, transactionGetBalance); var transactionGetBalanceResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto @@ -495,7 +495,7 @@ public async Task Transfer_Test() } [Fact] - public async Task GetTransactionFee_Test() + public void GetTransactionFee_Test() { var transactionResultDto = new TransactionResultDto { diff --git a/AElf.Client/AElf.Client.csproj b/AElf.Client/AElf.Client.csproj index 9510e3a..5a26839 100644 --- a/AElf.Client/AElf.Client.csproj +++ b/AElf.Client/AElf.Client.csproj @@ -9,15 +9,15 @@ - + - + - - + + diff --git a/AElf.Client/Dto/CreateRawTransactionInput.cs b/AElf.Client/Dto/CreateRawTransactionInput.cs index 3dc6d58..5966064 100644 --- a/AElf.Client/Dto/CreateRawTransactionInput.cs +++ b/AElf.Client/Dto/CreateRawTransactionInput.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using AElf.Types; namespace AElf.Client.Dto { @@ -46,7 +47,7 @@ public IEnumerable Validate(ValidationContext validationContex var validationResults = new List(); try { - AddressHelper.Base58StringToAddress(From); + Address.FromBase58(From); } catch { @@ -56,7 +57,7 @@ public IEnumerable Validate(ValidationContext validationContex try { - AddressHelper.Base58StringToAddress(To); + Address.FromBase58(To); } catch { @@ -66,7 +67,7 @@ public IEnumerable Validate(ValidationContext validationContex try { - HashHelper.HexStringToHash(RefBlockHash); + Hash.LoadFromHex(RefBlockHash); } catch { diff --git a/AElf.Client/Service/AElfClient.cs b/AElf.Client/Service/AElfClient.cs index fce755c..a3d6d9f 100644 --- a/AElf.Client/Service/AElfClient.cs +++ b/AElf.Client/Service/AElfClient.cs @@ -112,12 +112,12 @@ public async Task GenerateTransaction(string from, string to, var chainStatus = await GetChainStatusAsync(); var transaction = new Transaction { - From = AddressHelper.Base58StringToAddress(from), - To = AddressHelper.Base58StringToAddress(to), + From = Address.FromBase58(from), + To = Address.FromBase58(to), MethodName = methodName, Params = input.ToByteString(), RefBlockNumber = chainStatus.BestChainHeight, - RefBlockPrefix = ByteString.CopyFrom(HashHelper.HexStringToHash(chainStatus.BestChainHash).Value + RefBlockPrefix = ByteString.CopyFrom(Hash.LoadFromHex(chainStatus.BestChainHash).Value .Take(4).ToArray()) }; @@ -136,9 +136,9 @@ public async Task GenerateTransaction(string from, string to, /// public async Task GetFormattedAddress(Address address) { - var tokenContractAddress = await GetContractAddressByName(Hash.FromString("AElf.ContractNames.Token")); + var tokenContractAddress = await GetContractAddressByName(HashHelper.ComputeFrom("AElf.ContractNames.Token")); var fromAddress = GetAddressFromPrivateKey(ExamplePrivateKey); - var toAddress = tokenContractAddress.GetFormatted(); + var toAddress = tokenContractAddress.ToBase58(); var methodName = "GetPrimaryTokenSymbol"; var param = new Empty(); @@ -153,7 +153,7 @@ public async Task GetFormattedAddress(Address address) var symbol = StringValue.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(result)); var chainIdString = (await GetChainStatusAsync()).ChainId; - return $"{symbol.Value}_{address.GetFormatted()}_{chainIdString}"; + return $"{symbol.Value}_{address.ToBase58()}_{chainIdString}"; } /// @@ -183,7 +183,7 @@ public string GetAddressFromPubKey(string pubKey) { var publicKey = ByteArrayHelper.HexStringToByteArray(pubKey); var address = Address.FromPublicKey(publicKey); - return address.GetFormatted(); + return address.ToBase58(); } /// @@ -194,12 +194,12 @@ public string GetAddressFromPubKey(string pubKey) public string GetAddressFromPrivateKey(string privateKeyHex) { var address = Address.FromPublicKey(GetAElfKeyPair(privateKeyHex).PublicKey); - return address.GetFormatted(); + return address.ToBase58(); } public Address GetBase58String(string base58String) { - return AddressHelper.Base58StringToAddress(base58String); + return Address.FromBase58(base58String); } public KeyPairInfo GenerateKeyPairInfo() @@ -238,7 +238,7 @@ private void AssertValidAddress(params string[] addresses) { foreach (var address in addresses) { - AddressHelper.Base58StringToAddress(address); + Types.Address.FromBase58(address); } } catch (Exception) @@ -253,7 +253,7 @@ private void AssertValidHash(params string[] hashes) { foreach (var hash in hashes) { - HashHelper.HexStringToHash(hash); + Hash.LoadFromHex(hash); } } catch (Exception) @@ -268,7 +268,7 @@ private void AssertValidTransactionId(params string[] transactionIds) { foreach (var transactionId in transactionIds) { - HashHelper.HexStringToHash(transactionId); + Hash.LoadFromHex(transactionId); } } catch (Exception) From 7aea61216344665c68f34f0e7a8d9639218c7123 Mon Sep 17 00:00:00 2001 From: jinpeng wang Date: Thu, 7 May 2020 12:00:23 +0800 Subject: [PATCH 31/70] change ci node version to 1.0.0-preview2 --- scripts/aelf-node/start-mac.sh | 2 +- scripts/aelf-node/start-window.ps1 | 2 +- scripts/aelf-node/start.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/aelf-node/start-mac.sh b/scripts/aelf-node/start-mac.sh index 6625adb..09c3f09 100644 --- a/scripts/aelf-node/start-mac.sh +++ b/scripts/aelf-node/start-mac.sh @@ -3,7 +3,7 @@ brew services start redis brew install unzip mkdir -p ~/.local/share/aelf/keys cd ../../ -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview1/aelf.zip && unzip aelf.zip +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview2/aelf.zip && unzip aelf.zip cp scripts/aelf-node/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json ~/.local/share/aelf/keys/ cp scripts/aelf-node/app* aelf/ echo "start node" diff --git a/scripts/aelf-node/start-window.ps1 b/scripts/aelf-node/start-window.ps1 index 6f23955..76c5220 100644 --- a/scripts/aelf-node/start-window.ps1 +++ b/scripts/aelf-node/start-window.ps1 @@ -4,7 +4,7 @@ $job1 = Start-Job -ScriptBlock { cd D:\a\1\s\redis; .\redis-server.exe; } sleep 30 mkdir -p C:\Users\VssAdministrator\AppData\Local\aelf\keys cp -r scripts\aelf-node\keys\* C:\Users\VssAdministrator\AppData\Local\aelf\keys; -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview1/aelf.zip -OutFile aelf.zip ; +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview2/aelf.zip -OutFile aelf.zip ; Expand-Archive -Path aelf.zip -DestinationPath aelf ; cp scripts\aelf-node\appsettings.json aelf\aelf\appsettings.json ; cp scripts\aelf-node\appsettings.MainChain.TestNet.json aelf\aelf\appsettings.MainChain.TestNet.json ; diff --git a/scripts/aelf-node/start.sh b/scripts/aelf-node/start.sh index 59903c7..4140958 100644 --- a/scripts/aelf-node/start.sh +++ b/scripts/aelf-node/start.sh @@ -3,7 +3,7 @@ ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` sudo apt update && apt install unzip sudo mkdir -p /home/ubuntu/.ssh/aelf/keys && sudo mkdir -p /root/.ssh/aelf/keys cd ../../ -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview1/aelf.zip +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview2/aelf.zip sudo unzip aelf.zip sed -i "s/127.0.0.1/$ip/g" scripts/aelf-node/appsettings.json sudo mkdir -p aelf/aelf/keys From c7c076df0f6b387d2cdfddac76429467b4cda7d4 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Wed, 25 Nov 2020 10:42:01 +0800 Subject: [PATCH 32/70] update test node --- scripts/aelf-node/start-mac.sh | 2 +- scripts/aelf-node/start-window.ps1 | 2 +- scripts/aelf-node/start.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/aelf-node/start-mac.sh b/scripts/aelf-node/start-mac.sh index 09c3f09..34fddef 100644 --- a/scripts/aelf-node/start-mac.sh +++ b/scripts/aelf-node/start-mac.sh @@ -3,7 +3,7 @@ brew services start redis brew install unzip mkdir -p ~/.local/share/aelf/keys cd ../../ -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview2/aelf.zip && unzip aelf.zip +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-rc1/aelf.zip && unzip aelf.zip cp scripts/aelf-node/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json ~/.local/share/aelf/keys/ cp scripts/aelf-node/app* aelf/ echo "start node" diff --git a/scripts/aelf-node/start-window.ps1 b/scripts/aelf-node/start-window.ps1 index 76c5220..79a86e7 100644 --- a/scripts/aelf-node/start-window.ps1 +++ b/scripts/aelf-node/start-window.ps1 @@ -4,7 +4,7 @@ $job1 = Start-Job -ScriptBlock { cd D:\a\1\s\redis; .\redis-server.exe; } sleep 30 mkdir -p C:\Users\VssAdministrator\AppData\Local\aelf\keys cp -r scripts\aelf-node\keys\* C:\Users\VssAdministrator\AppData\Local\aelf\keys; -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview2/aelf.zip -OutFile aelf.zip ; +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-rc1/aelf.zip -OutFile aelf.zip ; Expand-Archive -Path aelf.zip -DestinationPath aelf ; cp scripts\aelf-node\appsettings.json aelf\aelf\appsettings.json ; cp scripts\aelf-node\appsettings.MainChain.TestNet.json aelf\aelf\appsettings.MainChain.TestNet.json ; diff --git a/scripts/aelf-node/start.sh b/scripts/aelf-node/start.sh index 4140958..8792f8b 100644 --- a/scripts/aelf-node/start.sh +++ b/scripts/aelf-node/start.sh @@ -3,7 +3,7 @@ ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` sudo apt update && apt install unzip sudo mkdir -p /home/ubuntu/.ssh/aelf/keys && sudo mkdir -p /root/.ssh/aelf/keys cd ../../ -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-preview2/aelf.zip +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-rc1/aelf.zip sudo unzip aelf.zip sed -i "s/127.0.0.1/$ip/g" scripts/aelf-node/appsettings.json sudo mkdir -p aelf/aelf/keys From 380ca69c386b67997e5c378ceb71737029a435d5 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Wed, 25 Nov 2020 11:12:40 +0800 Subject: [PATCH 33/70] fix test --- AElf.Client.Test/ClientTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index f3601f6..859b298 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -382,7 +382,7 @@ public async Task GetTransactionResults_Test() var transactionResults = await Client.GetTransactionResultsAsync(blockHash, 0, 2); foreach (var transaction in transactionResults) { - Assert.True(transaction.Status == TransactionResultStatus.Mined.ToString()); + Assert.True(transaction.Status == TransactionResultStatus.Mined.ToString().ToUpper()); } } From ab73eef8bc857973e8fbbc629a2ab1e02fbfc97a Mon Sep 17 00:00:00 2001 From: zhxymh Date: Wed, 25 Nov 2020 15:40:26 +0800 Subject: [PATCH 34/70] update proto --- .../Protobuf/Proto/aedpos_contract.proto | 11 +- .../Proto/association_auth_contract.proto | 22 ++- .../Protobuf/Proto/basic_contract_zero.proto | 10 - AElf.Client/Protobuf/Proto/client.proto | 177 ++++++++++++++---- .../Protobuf/Proto/cross_chain_contract.proto | 6 +- .../Protobuf/Proto/election_contract.proto | 113 +++++++---- .../Proto/parliament_auth_contract.proto | 12 +- .../Protobuf/Proto/profit_contract.proto | 64 +++++-- .../Proto/referendum_auth_contract.proto | 21 ++- .../Protobuf/Proto/resource_contract.proto | 30 --- .../Proto/toekn_converter_contract.proto | 14 +- .../Protobuf/Proto/token_contract.proto | 83 +++++--- .../Protobuf/Proto/transaction_fee.proto | 3 + .../Protobuf/Proto/treasury_contract.proto | 6 +- .../Protobuf/Proto/vote_contract.proto | 38 +++- 15 files changed, 432 insertions(+), 178 deletions(-) delete mode 100644 AElf.Client/Protobuf/Proto/basic_contract_zero.proto delete mode 100644 AElf.Client/Protobuf/Proto/resource_contract.proto diff --git a/AElf.Client/Protobuf/Proto/aedpos_contract.proto b/AElf.Client/Protobuf/Proto/aedpos_contract.proto index bdda35a..b4e1c4c 100644 --- a/AElf.Client/Protobuf/Proto/aedpos_contract.proto +++ b/AElf.Client/Protobuf/Proto/aedpos_contract.proto @@ -4,18 +4,23 @@ option csharp_namespace = "AElf.Client.Consensus.AEDPoS"; //aedpos_contract message MinerList { + // The miners public key list. repeated bytes pubkeys = 1; } message PubkeyList { - repeated string pubkeys = 1; + // Candidates’ public keys + repeated bytes value = 1; } message MinerListWithRoundNumber { + // The list of miners. MinerList miner_list = 1; - sint64 round_number = 2; + // The round number. + int64 round_number = 2; } message GetMinerListInput { - sint64 term_number = 1; + // The term number. + int64 term_number = 1; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/association_auth_contract.proto b/AElf.Client/Protobuf/Proto/association_auth_contract.proto index 3d5f201..67602cd 100644 --- a/AElf.Client/Protobuf/Proto/association_auth_contract.proto +++ b/AElf.Client/Protobuf/Proto/association_auth_contract.proto @@ -6,14 +6,16 @@ option csharp_namespace = "AElf.Client.AssociationAuth"; // association_auth_contract message Organization{ - int32 release_threshold = 1; - repeated Reviewer reviewers = 2; - int32 proposer_threshold = 3; - client.Address organization_address = 4; - client.Hash organization_hash = 5; -} - -message Reviewer { - client.Address address = 1; - int32 weight = 2; + // Indicates if proposals need authority to be created. + bool proposer_authority_required = 1; + // The organization address. + client.Address organization_address = 2; + // The organization id. + client.Hash organization_hash = 3; + // The threshold for releasing the proposal. + client.ProposalReleaseThreshold proposal_release_threshold = 4; + // Indicates if parliament member can propose to this organization. + bool parliament_member_proposing_allowed = 5; + // The creation token is for organization address generation. + client.Hash creation_token = 6; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/basic_contract_zero.proto b/AElf.Client/Protobuf/Proto/basic_contract_zero.proto deleted file mode 100644 index a6f1561..0000000 --- a/AElf.Client/Protobuf/Proto/basic_contract_zero.proto +++ /dev/null @@ -1,10 +0,0 @@ -syntax = "proto3"; - -import "client.proto"; - -option csharp_namespace = "AElf.Client.Genesis"; - -//basic_contract_zero -message AddressList { - repeated client.Address value = 1; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/client.proto b/AElf.Client/Protobuf/Proto/client.proto index bde9631..2e2ce6e 100644 --- a/AElf.Client/Protobuf/Proto/client.proto +++ b/AElf.Client/Protobuf/Proto/client.proto @@ -41,103 +41,169 @@ message StatePath { } message SmartContractRegistration { - int32 category = 1; + sint32 category = 1; bytes code = 2; Hash code_hash = 3; + bool is_system_contract = 4; + int32 version = 5; } //acs0 message ContractInfo { - uint64 serial_number = 1; - int32 category = 3; - Hash code_hash = 4; + // The serial number of the contract. + int64 serial_number = 1; + // The author of the contract, this is the person who deployed the contract. + client.Address author = 2; + // The category of contract code(0: C#). + sint32 category = 3; + // The hash of the contract code. + client.Hash code_hash = 4; + // Whether it is a system contract. bool is_system_contract = 5; + // The version of the current contract. + int32 version = 6; } //acs1 message MethodFees { + // The name of the method to be charged. string method_name = 1; + // List of fees to be charged. repeated MethodFee fees = 2; + // Optional based on the implementation of SetMethodFee method. + bool is_size_fee_free = 3; } message MethodFee { - string symbol = 1; - sint64 basic_fee = 2; + // The name of the method to be charged. + string method_name = 1; + // List of fees to be charged. + repeated MethodFee fees = 2; + // Optional based on the implementation of SetMethodFee method. + bool is_size_fee_free = 3; } //acs2 message ResourceInfo { - repeated ScopedStatePath paths = 1; - bool non_parallelizable = 2; + // The state path that depends on when writing. + repeated client.ScopedStatePath write_paths = 1; + // The state path that depends on when reading. + repeated client.ScopedStatePath read_paths = 2; + // Whether the transaction is not executed in parallel. + bool non_parallelizable = 3; } // acs3 message ProposalOutput { - Hash proposal_id = 1; + // The id of the proposal. + client.Hash proposal_id = 1; + // The method that this proposal will call when being released. string contract_method_name = 2; - Address to_address = 3; + // The address of the target contract. + client.Address to_address = 3; + // The parameters of the release transaction. bytes params = 4; + // The date at which this proposal will expire. google.protobuf.Timestamp expired_time = 5; - Address organization_address = 6; - Address proposer = 7; + // The address of this proposals organization. + client.Address organization_address = 6; + // The address of the proposer of this proposal. + client.Address proposer = 7; + // Indicates if this proposal is releasable. bool to_be_released = 8; + // Approval count for this proposal. + int64 approval_count = 9; + // Rejection count for this proposal. + int64 rejection_count = 10; + // Abstention count for this proposal. + int64 abstention_count = 11; +} + +message ProposalReleaseThreshold { + // The value for the minimum approval threshold. + int64 minimal_approval_threshold = 1; + // The value for the maximal rejection threshold. + int64 maximal_rejection_threshold = 2; + // The value for the maximal abstention threshold. + int64 maximal_abstention_threshold = 3; + // The value for the minimal vote threshold. + int64 minimal_vote_threshold = 4; +} + +message ProposerWhiteList{ + // The address of the proposers + repeated Address proposers = 1; } //acs4 message ValidationResult { + // Is successful. bool success = 1; + // The error message. string message = 2; + // Whether to trigger mining again. + bool is_re_trigger = 3; } //acs5 message MethodCallingThreshold { - map symbol_to_amount = 1;// The order matters. + // The threshold for method calling, token symbol -> amount. + map symbol_to_amount = 1; + // The type of threshold check. ThresholdCheckType threshold_check_type = 2; } enum ThresholdCheckType { + // Check balance only. BALANCE = 0; + // Check balance and allowance at the same time. ALLOWANCE = 1; } -//acs7 -message SideChainIdAndHeightDict { - map id_height_dict = 1; -} - message SideChainIndexingInformationList { + // A list contains indexing information of side chains. repeated SideChainIndexingInformation indexing_information_list = 1; } message SideChainIndexingInformation { + // The side chain id. int32 chain_id = 1; + // The indexed height. int64 indexed_height = 2; - int64 to_be_indexed_count = 3; } message CrossChainBlockData { - repeated SideChainBlockData side_chain_block_data = 1; - repeated ParentChainBlockData parent_chain_block_data = 2; - int64 previous_block_height = 3; + // The side chain block data list to index. + repeated SideChainBlockData side_chain_block_data_list = 1; + // The parent chain block data list to index. + repeated ParentChainBlockData parent_chain_block_data_list = 2; } message SideChainBlockData { + // The height of side chain block. int64 height = 1; - Hash block_header_hash = 2; - Hash transaction_status_merkle_tree_root = 3; + // The hash of side chain block. + client.Hash block_header_hash = 2; + // The merkle tree root computing from transactions status in side chain block. + client.Hash transaction_status_merkle_tree_root = 3; + // The id of side chain. int32 chain_id = 4; } message ParentChainBlockData { + // The height of parent chain. int64 height = 1; + // The merkle tree root computing from side chain roots. CrossChainExtraData cross_chain_extra_data = 2; + // The parent chain id. int32 chain_id = 3; - Hash transaction_status_merkle_tree_root = 4; - + // The merkle tree root computing from transactions status in parent chain block. + client.Hash transaction_status_merkle_tree_root = 4; // Indexed block height from side chain and merkle path for this side chain block - map indexed_merkle_path = 5; + map indexed_merkle_path = 5; + // Extra data map. map extra_data = 6; } @@ -146,21 +212,58 @@ message CrossChainExtraData { Hash transaction_status_merkle_tree_root = 1; } -message IndexedSideChainBlockData{ - repeated SideChainBlockData side_chain_block_data = 1; -} - message CrossChainMerkleProofContext { + // The height of parent chain bound up with side chain. int64 bound_parent_chain_height = 1; - MerklePath merkle_path_from_parent_chain = 2; + // The merkle path generated from parent chain. + client.MerklePath merkle_path_from_parent_chain = 2; } message ChainInitializationData { + // The id of side chain. int32 chain_id = 1; - Address creator = 2; + // The side chain creator. + client.Address creator = 2; + // The timestamp for side chain creation. google.protobuf.Timestamp creation_timestamp = 3; - repeated bytes extra_information = 4; - int64 creation_height_on_parent_chain = 5; - bool chain_creator_privilege_preserved = 6; - string side_chain_token_symbol = 7; + // The height of side chain creation on parent chain. + int64 creation_height_on_parent_chain = 4; + // Creator privilege boolean flag: True if chain creator privilege preserved, otherwise false. + bool chain_creator_privilege_preserved = 5; + // Parent chain token contract address. + client.Address parent_chain_token_contract_address = 6; + // Initial consensus information. + ChainInitializationConsensusInfo chain_initialization_consensus_info = 7; + // The native token info. + bytes native_token_info_data = 8; + // The resource token information. + ResourceTokenInfo resource_token_info = 9; + // The chain primary token information. + ChainPrimaryTokenInfo chain_primary_token_info = 10; +} + +message ResourceTokenInfo{ + // The resource token information. + bytes resource_token_list_data = 1; + // The initial resource token amount. + map initial_resource_amount = 2; +} + +message ChainPrimaryTokenInfo{ + // The side chain primary token data. + bytes chain_primary_token_data = 1; + // The side chain primary token initial issue list. + repeated SideChainTokenInitialIssue side_chain_token_initial_issue_list = 2; +} + +message ChainInitializationConsensusInfo{ + // Initial consensus data. + bytes initial_consensus_data = 1; +} + +message SideChainTokenInitialIssue{ + // The account that will be issued. + client.Address address = 1; + // The amount that will be issued. + int64 amount = 2; } diff --git a/AElf.Client/Protobuf/Proto/cross_chain_contract.proto b/AElf.Client/Protobuf/Proto/cross_chain_contract.proto index 9babbaa..32228d8 100644 --- a/AElf.Client/Protobuf/Proto/cross_chain_contract.proto +++ b/AElf.Client/Protobuf/Proto/cross_chain_contract.proto @@ -6,8 +6,12 @@ import "client.proto"; //cross_chain_contract message VerifyTransactionInput { + // The cross chain transaction id to verify. client.Hash transaction_id = 1; + // The merkle path of the transaction. client.MerklePath path = 2; - sint64 parent_chain_height = 3; + // The height of parent chain that indexing this transaction. + int64 parent_chain_height = 3; + // The chain if to verify. int32 verified_chain_id = 4; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/election_contract.proto b/AElf.Client/Protobuf/Proto/election_contract.proto index bb86cd8..2e94912 100644 --- a/AElf.Client/Protobuf/Proto/election_contract.proto +++ b/AElf.Client/Protobuf/Proto/election_contract.proto @@ -7,93 +7,142 @@ import "client.proto"; //election_contract message CandidateInformation { + // Candidate’s public key. string pubkey = 1; - repeated sint64 terms = 2; - sint64 produced_blocks = 3; - sint64 missed_time_slots = 4; - sint64 continual_appointment_count = 5; + // The number of terms that the candidate is elected. + repeated int64 terms = 2; + // The number of blocks the candidate has produced. + int64 produced_blocks = 3; + // The time slot for which the candidate failed to produce blocks. + int64 missed_time_slots = 4; + // The count of continual appointment. + int64 continual_appointment_count = 5; + // The transaction id when the candidate announced. client.Hash announcement_transaction_id = 6; + // Indicate whether the candidate can be elected in the current term. bool is_current_candidate = 7; } message GetTermSnapshotInput { - sint64 term_number = 1; + // The term number. + int64 term_number = 1; } message TermSnapshot { - sint64 end_round_number = 1; - sint64 mined_blocks = 2; - map election_result = 3; + // The end round number of this term. + int64 end_round_number = 1; + // The number of blocks mined in this term. + int64 mined_blocks = 2; + // The election result, candidates’ public key -> number of votes. + map election_result = 3; } message GetElectionResultInput { - sint64 term_number = 1; + // The term number. + int64 term_number = 1; } message ElectionResult { - sint64 term_number = 1; - map results = 2; + // The term number + int64 term_number = 1; + // The election result, candidates’ public key -> number of votes. + map results = 2; + // Whether an election is currently being held. bool is_active = 3; } message ElectorVote { - repeated client.Hash active_voting_record_ids = 1;// Not withdrawn. + // The active voting record ids. + repeated client.Hash active_voting_record_ids = 1; + // The voting record ids that were withdrawn. repeated client.Hash withdrawn_voting_record_ids = 2; - sint64 active_voted_votes_amount = 3; - sint64 all_voted_votes_amount = 4; + // The total number of active votes. + int64 active_voted_votes_amount = 3; + // The total number of votes (including the number of votes withdrawn). + int64 all_voted_votes_amount = 4; + // The active voting records. repeated ElectionVotingRecord active_voting_records = 5; + // The voting records that were withdrawn. repeated ElectionVotingRecord withdrawn_votes_records = 6; + // Public key for voter. bytes pubkey = 7; } message ElectionVotingRecord { + // The address of voter. client.Address voter = 1; + // The public key of candidate. string candidate = 2; - sint64 amount = 3; - sint64 term_number = 4; + // Amount of voting. + int64 amount = 3; + // The term number of voting. + int64 term_number = 4; + // The vote id. client.Hash vote_id = 5; - sint64 lock_time = 7; - google.protobuf.Timestamp unlock_timestamp = 10; - google.protobuf.Timestamp withdraw_timestamp = 11; - google.protobuf.Timestamp vote_timestamp = 12; - bool is_withdrawn = 13; - sint64 weight = 14; - bool is_change_target = 15; + // Vote lock time. + int64 lock_time = 6; + // The unlock timestamp. + google.protobuf.Timestamp unlock_timestamp = 7; + // The withdraw timestamp. + google.protobuf.Timestamp withdraw_timestamp = 8; + // The vote timestamp. + google.protobuf.Timestamp vote_timestamp = 9; + // Indicates if the vote has been withdrawn. + bool is_withdrawn = 10; + // Vote weight for sharing bonus. + int64 weight = 11; + // Whether vote others. + bool is_change_target = 12; } message CandidateVote { + // The active voting record ids obtained. repeated client.Hash obtained_active_voting_record_ids = 1; + // The active voting record ids that were withdrawn. repeated client.Hash obtained_withdrawn_voting_record_ids = 2; - sint64 obtained_active_voted_votes_amount = 3; - sint64 all_obtained_voted_votes_amount = 4; + // The total number of active votes obtained. + int64 obtained_active_voted_votes_amount = 3; + // The total number of votes obtained. + int64 all_obtained_voted_votes_amount = 4; + // The active voting records. repeated ElectionVotingRecord obtained_active_voting_records = 5; + // The voting records that were withdrawn. repeated ElectionVotingRecord obtained_withdrawn_votes_records = 6; + // Public key for candidate. bytes pubkey = 7; } message GetWelfareRewardAmountSampleInput { - repeated sint64 value = 1; + // Token lock time. + repeated int64 value = 1; } message GetWelfareRewardAmountSampleOutput { - repeated sint64 value = 1; + // The weight calculated. + repeated int64 value = 1; } message PageInformation { - sint32 start = 1; - sint32 length = 2; + // The start index. + int32 start = 1; + // The number of records. + int32 length = 2; } message CandidateDetail { + // The candidate information. CandidateInformation candidate_information = 1; - sint64 obtained_votes_amount = 2; + // The number of votes a candidate has obtained. + int64 obtained_votes_amount = 2; } message GetPageableCandidateInformationOutput { + // The details of the candidates. repeated CandidateDetail value = 1; } message DataCenterRankingList { - map data_centers = 1; - sint64 minimum_votes = 2; + // The top n * 5 candidates with vote amount, candidate public key -> vote amount. + map data_centers = 1; + int64 minimum_votes = 2; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/parliament_auth_contract.proto b/AElf.Client/Protobuf/Proto/parliament_auth_contract.proto index 512c1a4..68b3aae 100644 --- a/AElf.Client/Protobuf/Proto/parliament_auth_contract.proto +++ b/AElf.Client/Protobuf/Proto/parliament_auth_contract.proto @@ -6,11 +6,21 @@ option csharp_namespace = "AElf.Client.ParliamentAuth"; //parliament_auth message ProposalIdList{ + // The list of proposal ids. repeated client.Hash proposal_ids = 1; } message Organization { - sint32 release_threshold = 1; + // Indicates if proposals need authority to be created. + bool proposer_authority_required = 1; + // The organization address. client.Address organization_address = 2; + // The organization id. client.Hash organization_hash = 3; + // The threshold for releasing the proposal. + client.ProposalReleaseThreshold proposal_release_threshold = 4; + // Indicates if parliament member can propose to this organization. + bool parliament_member_proposing_allowed = 5; + // The creation token is for organization address generation. + client.Hash creation_token = 6; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/profit_contract.proto b/AElf.Client/Protobuf/Proto/profit_contract.proto index c6178cd..3910e0d 100644 --- a/AElf.Client/Protobuf/Proto/profit_contract.proto +++ b/AElf.Client/Protobuf/Proto/profit_contract.proto @@ -6,61 +6,93 @@ option csharp_namespace = "AElf.Client.Profit"; //profit_contract message CreatedSchemeIds { + // The scheme ids. repeated client.Hash scheme_ids = 1; } message GetManagingSchemeIdsInput { + // The manager address. client.Address manager = 1; } message SchemeBeneficiaryShare { + // The id of the sub scheme. client.Hash scheme_id = 1; - sint64 shares = 2; + // The weight of the sub scheme. + int64 shares = 2; } message Scheme { + // The virtual address of the scheme. client.Address virtual_address = 1; - sint64 total_shares = 2; - map undistributed_profits = 3;// token symbol -> amount - sint64 current_period = 4; + // The total weight of the scheme. + int64 total_shares = 2; + // The manager of the scheme. + client.Address manager = 3; + // The current period. + int64 current_period = 4; + // Sub schemes information. repeated SchemeBeneficiaryShare sub_schemes = 5; - sint64 profit_receiving_due_period_count = 7; + // Whether you can directly remove the beneficiary. + bool can_remove_beneficiary_directly = 6; + // Period of profit distribution. + int64 profit_receiving_due_period_count = 7; + // Whether all the schemes balance will be distributed during distribution each period. bool is_release_all_balance_every_time_by_default = 8; + // The is of the scheme. client.Hash scheme_id = 9; - sint32 delay_distribute_period_count = 10; - map cached_delay_total_shares = 11;// period -> total shares, max elements count should be delay_distribute_period_count - client.Address manager = 12; + // Delay distribute period. + int32 delay_distribute_period_count = 10; + // Record the scheme's current total share for deferred distribution of benefits, period -> total shares. + map cached_delay_total_shares = 11; + // The received token symbols. + repeated string received_token_symbols = 12; } message SchemePeriod { + // The scheme id. client.Hash scheme_id = 1; - sint64 period = 2; + // The period number. + int64 period = 2; } message DistributedProfitsInfo { - sint64 total_shares = 1; - map profits_amount = 2; + // The total amount of shares in this scheme at the current period. + int64 total_shares = 1; + // The contributed amount in this scheme at the current period. + map amounts_map = 2; + // Whether released. bool is_released = 3; } message GetProfitDetailsInput { + // The scheme id. client.Hash scheme_id = 1; + // The address of beneficiary. client.Address beneficiary = 2; } message ProfitDetails { + // The profit information. repeated ProfitDetail details = 1; } message ProfitDetail { - sint64 start_period = 1; - sint64 end_period = 2; - sint64 shares = 3; - sint64 last_profit_period = 4; + // The start period number. + int64 start_period = 1; + // The end period number. + int64 end_period = 2; + // The weight of the proceeds on the current period of the scheme. + int64 shares = 3; + // The last period number that the beneficiary received the profit. + int64 last_profit_period = 4; + // Whether the weight has been removed. bool is_weight_removed = 5; } message ClaimProfitsInput { + // The scheme id. client.Hash scheme_id = 1; - string symbol = 2; + // The address of beneficiary. + client.Address beneficiary = 2; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/referendum_auth_contract.proto b/AElf.Client/Protobuf/Proto/referendum_auth_contract.proto index 1fba552..44b2e9a 100644 --- a/AElf.Client/Protobuf/Proto/referendum_auth_contract.proto +++ b/AElf.Client/Protobuf/Proto/referendum_auth_contract.proto @@ -5,8 +5,21 @@ import "client.proto"; option csharp_namespace = "AElf.Client.ReferendumAuth"; message Organization { - int64 release_threshold = 1; - string token_symbol = 2; - client.Address organization_address = 3; - client.Hash organization_hash = 4; + // The organization members. + OrganizationMemberList organization_member_list = 1; + // The threshold for releasing the proposal. + client.ProposalReleaseThreshold proposal_release_threshold = 2; + // The proposer whitelist. + client.ProposerWhiteList proposer_white_list = 3; + // The address of organization. + client.Address organization_address = 4; + // The organizations id. + client.Hash organization_hash = 5; + // The creation token is for organization address generation. + client.Hash creation_token = 6; +} + +message OrganizationMemberList { + // The address of organization members. + repeated client.Address organization_members = 1; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/resource_contract.proto b/AElf.Client/Protobuf/Proto/resource_contract.proto deleted file mode 100644 index 6e759cb..0000000 --- a/AElf.Client/Protobuf/Proto/resource_contract.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; - -import "client.proto"; - -option csharp_namespace = "AElf.Client.Resource"; - -message ResourceId { - ResourceType type = 1; -} - -enum ResourceType { - UNDEFINED_RESOURCE_TYPE = 0; - RAM = 1; - CPU = 2; - NET = 3; - STO = 4; -} - -message Converter { - sint64 res_balance = 1; - sint64 elf_balance = 2; - sint64 res_weight = 3; // Weight based on MAX of 1,000,000 - sint64 elf_weight = 4; // Weight based on MAX of 1,000,000 - ResourceType type = 5; -} - -message UserResourceId { - client.Address address = 1; - ResourceType type = 2; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/toekn_converter_contract.proto b/AElf.Client/Protobuf/Proto/toekn_converter_contract.proto index 6882c4a..d33a4c5 100644 --- a/AElf.Client/Protobuf/Proto/toekn_converter_contract.proto +++ b/AElf.Client/Protobuf/Proto/toekn_converter_contract.proto @@ -4,13 +4,23 @@ option csharp_namespace = "AElf.Client.TokenConverter"; //token converter message TokenSymbol { + // The token symbol. string symbol = 1; } message Connector { + // The token symbol. string symbol = 1; - sint64 virtual_balance = 2; + // The virtual balance for base token. + int64 virtual_balance = 2; + // The calculated weight value for this Connector. string weight = 3; - bool is_virtual_balance_enabled = 4; // true if virtual balance is enabled, false if not + // Whether to use Virtual Balance. + bool is_virtual_balance_enabled = 4; + // Whether the connector is enabled. bool is_purchase_enabled = 5; + // Indicates its related connector, the pair connector includes a new created token connector and the base token connector. + string related_symbol = 6; + // Indicates if the connector is base token connector. + bool is_deposit_account = 7; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/token_contract.proto b/AElf.Client/Protobuf/Proto/token_contract.proto index 511e914..54070ff 100644 --- a/AElf.Client/Protobuf/Proto/token_contract.proto +++ b/AElf.Client/Protobuf/Proto/token_contract.proto @@ -6,94 +6,131 @@ option csharp_namespace = "AElf.Client.MultiToken"; //tokenContract message TokenInfo { + // The symbol of the token.f string symbol = 1; - string tokenName = 2; - sint64 supply = 3; - sint64 totalSupply = 4; - sint32 decimals = 5; + // The full name of the token. + string token_name = 2; + // The current supply of the token. + int64 supply = 3; + // The total supply of the token. + int64 total_supply = 4; + // The precision of the token. + int32 decimals = 5; + // The address that created the token. client.Address issuer = 6; + // A flag indicating if this token is burnable. bool is_burnable = 7; - bool is_transfer_disabled = 8; - sint32 issue_chain_id = 9; - sint64 burned = 10; + // The chain id of the token. + int32 issue_chain_id = 8; + // The amount of issued tokens. + int64 issued = 9; } message GetTokenInfoInput { + // The symbol of token. string symbol = 1; } message TokenInfoList { + // List of token information. repeated TokenInfo value = 1; } message GetBalanceInput { + // The symbol of token. string symbol = 1; + // The target address of the query. client.Address owner = 2; } message GetBalanceOutput { + // The symbol of token. string symbol = 1; + // The target address of the query. client.Address owner = 2; - sint64 balance = 3; + // The balance of the owner. + int64 balance = 3; } message GetAllowanceInput { + // The symbol of token. string symbol = 1; + // The address of the token owner. client.Address owner = 2; + // The address of the spender. client.Address spender = 3; } message GetAllowanceOutput { + // The symbol of token. string symbol = 1; + // The address of the token owner. client.Address owner = 2; + // The address of the spender. client.Address spender = 3; - sint64 allowance = 4; + // The amount of allowance. + int64 allowance = 4; } message IsInWhiteListInput { + // The symbol of token. string symbol = 1; + // The address to check. client.Address address = 2; } -message ProfitReceivingInformation { - client.Address contract_address = 1; - client.Address profit_receiver_address = 2; - sint32 donation_parts_per_hundred = 3; -} - message GetLockedAmountInput { + // The address of the lock. client.Address address = 1; - string symbol = 3; - client.Hash lock_id = 4; + // The token symbol. + string symbol = 2; + // The id of the lock. + client.Hash lock_id = 3; } message GetLockedAmountOutput { + // The address of the lock. client.Address address = 1; - string symbol = 3; - client.Hash lock_id = 4; - sint64 amount = 5; + // The token symbol. + string symbol = 2; + // The id of the lock. + client.Hash lock_id = 3; + // The locked amount. + int64 amount = 4; } message GetVirtualAddressForLockingInput { + // The address of the lock. client.Address address = 1; - client.Hash lock_id = 3; + // The id of the lock. + client.Hash lock_id = 2; } message GetCrossChainTransferTokenContractAddressInput { + // The chain id. int32 chainId = 1; } message TransferFromInput { + // The source address of the token. client.Address from = 1; + // The destination address of the token. client.Address to = 2; + // The symbol of the token to transfer. string symbol = 3; - sint64 amount = 4; + // The amount to transfer. + int64 amount = 4; + // The memo. string memo = 5; } message TransferInput { + // The receiver of the token. client.Address to = 1; + // The token symbol to transfer. string symbol = 2; - sint64 amount = 3; + // The amount to to transfer. + int64 amount = 3; + // The memo. string memo = 4; } diff --git a/AElf.Client/Protobuf/Proto/transaction_fee.proto b/AElf.Client/Protobuf/Proto/transaction_fee.proto index 023f315..9d3080c 100644 --- a/AElf.Client/Protobuf/Proto/transaction_fee.proto +++ b/AElf.Client/Protobuf/Proto/transaction_fee.proto @@ -3,6 +3,7 @@ syntax = "proto3"; package client; import "options.proto"; +import "client.proto"; option csharp_namespace = "AElf.Client.MultiToken"; @@ -32,10 +33,12 @@ message ResourceTokenCharged { option (client.is_event) = true; string symbol = 1; sint64 amount = 2; + Address contract_address = 3; } message ResourceTokenOwned { option (client.is_event) = true; string symbol = 1; sint64 amount = 2; + Address contract_address = 3; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/treasury_contract.proto b/AElf.Client/Protobuf/Proto/treasury_contract.proto index 31a93ee..460d03f 100644 --- a/AElf.Client/Protobuf/Proto/treasury_contract.proto +++ b/AElf.Client/Protobuf/Proto/treasury_contract.proto @@ -4,9 +4,11 @@ option csharp_namespace = "AElf.Client.Treasury"; //treasury_contract message GetWelfareRewardAmountSampleInput { - repeated sint64 value = 1; + // Token lock time. + repeated int64 value = 1; } message GetWelfareRewardAmountSampleOutput { - repeated sint64 value = 1; + // The weight calculated. + repeated int64 value = 1; } \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/vote_contract.proto b/AElf.Client/Protobuf/Proto/vote_contract.proto index 97ae0af..fff3d1c 100644 --- a/AElf.Client/Protobuf/Proto/vote_contract.proto +++ b/AElf.Client/Protobuf/Proto/vote_contract.proto @@ -6,49 +6,73 @@ import "google/protobuf/timestamp.proto"; option csharp_namespace = "AElf.Client.Vote"; message GetVotingItemInput { + // The voting activity id. client.Hash voting_item_id = 1; } message VotedItems { + // The voted ids. map voted_item_vote_ids = 1; } message VotedIds { + // The active vote ids. repeated client.Hash active_votes = 1; + // The withdrawn vote ids. repeated client.Hash withdrawn_votes = 2; } message GetVotingResultInput { + // The voting activity id. client.Hash voting_item_id = 1; - sint64 snapshot_number = 2; + // The snapshot number. + int64 snapshot_number = 2; } message VotingResult { + // The voting activity id. client.Hash voting_item_id = 1; - map results = 2; // option -> amount - sint64 snapshot_number = 3; - sint64 voters_count = 4; + // The voting result, option -> amount of votes, + map results = 2; + // The snapshot number. + int64 snapshot_number = 3; + // The total number of voters. + int64 voters_count = 4; + // The start time of this snapshot. google.protobuf.Timestamp snapshot_start_timestamp = 5; + // The end time of this snapshot. google.protobuf.Timestamp snapshot_end_timestamp = 6; - sint64 votes_amount = 7; + // Total votes received during the process of this snapshot. + int64 votes_amount = 7; } message VotingRecord { + // The voting activity id. client.Hash voting_item_id = 1; + // The address of voter. client.Address voter = 2; - sint64 snapshot_number = 3; - sint64 amount = 4; + // The snapshot number. + int64 snapshot_number = 3; + // The amount of vote. + int64 amount = 4; + // The time of withdraw. google.protobuf.Timestamp withdraw_timestamp = 5; + // The time of vote. google.protobuf.Timestamp vote_timestamp = 6; + // Whether the vote had been withdrawn. bool is_withdrawn = 7; + // The option voted. string option = 8; + // Whether vote others. bool is_change_target = 9; } message GetVotingRecordsInput { + // The vote ids. repeated client.Hash ids = 1; } message VotingRecords { + // The voting records. repeated VotingRecord records = 1; } From 160889a4192c67c8c9026f121ddc67e9d03fc922 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Fri, 27 Nov 2020 16:44:47 +0800 Subject: [PATCH 35/70] fix method name --- AElf.Client.Test/ClientTest.cs | 22 +++++++++++----------- AElf.Client/Service/AElfClient.cs | 20 ++++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 859b298..66c3d79 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -194,11 +194,11 @@ public async Task GetTransactionPoolStatus_Test() [Fact] public async Task ExecuteTransaction_Test() { - var toAddress = await Client.GetContractAddressByName(HashHelper.ComputeFrom("AElf.ContractNames.Token")); + var toAddress = await Client.GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); var methodName = "GetNativeTokenInfo"; var param = new Empty(); - var transaction = await Client.GenerateTransaction(_address, toAddress.ToBase58(), methodName, param); + var transaction = await Client.GenerateTransactionAsync(_address, toAddress.ToBase58(), methodName, param); var txWithSign = Client.SignTransaction(PrivateKey, transaction); var transactionResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto @@ -266,7 +266,7 @@ public async Task ExecuteRawTransaction_Test() rawTransactionResult.ShouldNotBeEmpty(); var consensusAddress = - (await Client.GetContractAddressByName(HashHelper.ComputeFrom("AElf.ContractNames.Consensus"))) + (await Client.GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Consensus"))) .ToBase58(); var addressResult = rawTransactionResult.Trim('"'); @@ -321,7 +321,7 @@ public async Task SendTransaction_Test() var methodName = ContractMethodName; var param = HashHelper.ComputeFrom("AElf.ContractNames.Vote"); - var transaction = await Client.GenerateTransaction(_address, toAddress, methodName, param); + var transaction = await Client.GenerateTransactionAsync(_address, toAddress, methodName, param); var txWithSign = Client.SignTransaction(PrivateKey, transaction); var result = await Client.SendTransactionAsync(new SendTransactionInput @@ -347,7 +347,7 @@ public async Task SendTransactions_Test() foreach (var param in parameters) { - var tx = await Client.GenerateTransaction(_address, toAddress, methodName, param); + var tx = await Client.GenerateTransactionAsync(_address, toAddress, methodName, param); var txWithSign = Client.SignTransaction(PrivateKey, tx); sb.Append(txWithSign.ToByteArray().ToHex() + ','); } @@ -410,7 +410,7 @@ public async Task GetChainId_Test() [Fact] public async Task IsConnected_Test() { - var isConnected = await Client.IsConnected(); + var isConnected = await Client.IsConnectedAsync(); isConnected.ShouldBeTrue(); } @@ -420,7 +420,7 @@ public async Task GetGenesisContractAddress_Test() var genesisAddress = await Client.GetGenesisContractAddressAsync(); genesisAddress.ShouldNotBeEmpty(); - var address = await Client.GetContractAddressByName(Hash.Empty); + var address = await Client.GetContractAddressByNameAsync(Hash.Empty); var genesisAddress2 = address.ToBase58(); Assert.True(genesisAddress == genesisAddress2); } @@ -428,7 +428,7 @@ public async Task GetGenesisContractAddress_Test() [Fact] public async Task GetFormattedAddress_Test() { - var result = await Client.GetFormattedAddress(Address.FromBase58(_address)); + var result = await Client.GetFormattedAddressAsync(Address.FromBase58(_address)); _testOutputHelper.WriteLine(result); Assert.True(result == $"ELF_{_address}_AELF"); } @@ -445,7 +445,7 @@ public void GetNewKeyPairInfo_Test() public async Task Transfer_Test() { var toAccount = Client.GenerateKeyPairInfo().Address; - var toAddress = await Client.GetContractAddressByName(HashHelper.ComputeFrom("AElf.ContractNames.Token")); + var toAddress = await Client.GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); var methodName = "Transfer"; var param = new TransferInput { @@ -454,7 +454,7 @@ public async Task Transfer_Test() Amount = 1000 }; - var transaction = await Client.GenerateTransaction(_address, toAddress.ToBase58(), methodName, param); + var transaction = await Client.GenerateTransactionAsync(_address, toAddress.ToBase58(), methodName, param); var txWithSign = Client.SignTransaction(PrivateKey, transaction); var result = await Client.SendTransactionAsync(new SendTransactionInput @@ -480,7 +480,7 @@ public async Task Transfer_Test() }; var transactionGetBalance = - await Client.GenerateTransaction(_address, toAddress.ToBase58(), "GetBalance", paramGetBalance); + await Client.GenerateTransactionAsync(_address, toAddress.ToBase58(), "GetBalance", paramGetBalance); var txWithSignGetBalance = Client.SignTransaction(PrivateKey, transactionGetBalance); var transactionGetBalanceResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto diff --git a/AElf.Client/Service/AElfClient.cs b/AElf.Client/Service/AElfClient.cs index a3d6d9f..e9637a8 100644 --- a/AElf.Client/Service/AElfClient.cs +++ b/AElf.Client/Service/AElfClient.cs @@ -15,10 +15,10 @@ namespace AElf.Client.Service { public interface IClientService { - Task IsConnected(); - Task GetFormattedAddress(Address address); + Task IsConnectedAsync(); + Task GetFormattedAddressAsync(Address address); Task GetGenesisContractAddressAsync(); - Task
GetContractAddressByName(Hash contractNameHash); + Task
GetContractAddressByNameAsync(Hash contractNameHash); string GetAddressFromPubKey(string pubKey); KeyPairInfo GenerateKeyPairInfo(); } @@ -47,7 +47,7 @@ public AElfClient(string baseUrl, int timeOut = 60) /// Verify whether this sdk successfully connects the chain. ///
/// IsConnected or not - public async Task IsConnected() + public async Task IsConnectedAsync() { try { @@ -78,11 +78,11 @@ public async Task GetGenesisContractAddressAsync() /// /// /// Address - public async Task
GetContractAddressByName(Hash contractNameHash) + public async Task
GetContractAddressByNameAsync(Hash contractNameHash) { var from = GetAddressFromPrivateKey(ExamplePrivateKey); var to = await GetGenesisContractAddressAsync(); - var transaction = await GenerateTransaction(from, to, "GetContractAddressByName", contractNameHash); + var transaction = await GenerateTransactionAsync(from, to, "GetContractAddressByName", contractNameHash); var txWithSig = SignTransaction(ExamplePrivateKey, transaction); var response = await ExecuteTransactionAsync(new ExecuteTransactionDto @@ -103,7 +103,7 @@ public async Task
GetContractAddressByName(Hash contractNameHash) /// /// /// Transaction unsigned - public async Task GenerateTransaction(string from, string to, + public async Task GenerateTransactionAsync(string from, string to, string methodName, IMessage input) { try @@ -134,15 +134,15 @@ public async Task GenerateTransaction(string from, string to, ///
/// /// - public async Task GetFormattedAddress(Address address) + public async Task GetFormattedAddressAsync(Address address) { - var tokenContractAddress = await GetContractAddressByName(HashHelper.ComputeFrom("AElf.ContractNames.Token")); + var tokenContractAddress = await GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); var fromAddress = GetAddressFromPrivateKey(ExamplePrivateKey); var toAddress = tokenContractAddress.ToBase58(); var methodName = "GetPrimaryTokenSymbol"; var param = new Empty(); - var transaction = await GenerateTransaction(fromAddress, toAddress, methodName, param); + var transaction = await GenerateTransactionAsync(fromAddress, toAddress, methodName, param); var txWithSign = SignTransaction(ExamplePrivateKey, transaction); var result = await ExecuteTransactionAsync(new ExecuteTransactionDto From a6491683cf15103d461621b10021d2a17d74abe3 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Fri, 27 Nov 2020 17:21:01 +0800 Subject: [PATCH 36/70] change target framework to netstandard2.0 --- AElf.Client/AElf.Client.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AElf.Client/AElf.Client.csproj b/AElf.Client/AElf.Client.csproj index 5a26839..9286d7c 100644 --- a/AElf.Client/AElf.Client.csproj +++ b/AElf.Client/AElf.Client.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + netstandard2.0 AElf.Client This is a C# client library, used to communicate with the AElf API. AElf From 19127f2b65ebc9b76e213e81280b70893bfab730 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Thu, 10 Dec 2020 11:36:47 +0800 Subject: [PATCH 37/70] update test node to v1.0.0 --- scripts/aelf-node/start-mac.sh | 2 +- scripts/aelf-node/start-window.ps1 | 2 +- scripts/aelf-node/start.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/aelf-node/start-mac.sh b/scripts/aelf-node/start-mac.sh index 34fddef..e580f84 100644 --- a/scripts/aelf-node/start-mac.sh +++ b/scripts/aelf-node/start-mac.sh @@ -3,7 +3,7 @@ brew services start redis brew install unzip mkdir -p ~/.local/share/aelf/keys cd ../../ -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-rc1/aelf.zip && unzip aelf.zip +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0/aelf.zip && unzip aelf.zip cp scripts/aelf-node/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json ~/.local/share/aelf/keys/ cp scripts/aelf-node/app* aelf/ echo "start node" diff --git a/scripts/aelf-node/start-window.ps1 b/scripts/aelf-node/start-window.ps1 index 79a86e7..c708a48 100644 --- a/scripts/aelf-node/start-window.ps1 +++ b/scripts/aelf-node/start-window.ps1 @@ -4,7 +4,7 @@ $job1 = Start-Job -ScriptBlock { cd D:\a\1\s\redis; .\redis-server.exe; } sleep 30 mkdir -p C:\Users\VssAdministrator\AppData\Local\aelf\keys cp -r scripts\aelf-node\keys\* C:\Users\VssAdministrator\AppData\Local\aelf\keys; -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-rc1/aelf.zip -OutFile aelf.zip ; +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0/aelf.zip -OutFile aelf.zip ; Expand-Archive -Path aelf.zip -DestinationPath aelf ; cp scripts\aelf-node\appsettings.json aelf\aelf\appsettings.json ; cp scripts\aelf-node\appsettings.MainChain.TestNet.json aelf\aelf\appsettings.MainChain.TestNet.json ; diff --git a/scripts/aelf-node/start.sh b/scripts/aelf-node/start.sh index 8792f8b..138b5c5 100644 --- a/scripts/aelf-node/start.sh +++ b/scripts/aelf-node/start.sh @@ -3,7 +3,7 @@ ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` sudo apt update && apt install unzip sudo mkdir -p /home/ubuntu/.ssh/aelf/keys && sudo mkdir -p /root/.ssh/aelf/keys cd ../../ -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0-rc1/aelf.zip +wget https://github.com/AElfProject/AElf/releases/download/v1.0.0/aelf.zip sudo unzip aelf.zip sed -i "s/127.0.0.1/$ip/g" scripts/aelf-node/appsettings.json sudo mkdir -p aelf/aelf/keys From aa4835ac7f7371ce2ccce533808c5c98b229cbe1 Mon Sep 17 00:00:00 2001 From: zhxymh Date: Fri, 11 Dec 2020 16:59:33 +0800 Subject: [PATCH 38/70] update package --- AElf.Client/AElf.Client.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AElf.Client/AElf.Client.csproj b/AElf.Client/AElf.Client.csproj index 9286d7c..497bf9d 100644 --- a/AElf.Client/AElf.Client.csproj +++ b/AElf.Client/AElf.Client.csproj @@ -9,15 +9,15 @@ - + - - + + From c5640ebcc43d62e5bef2df982d2cbfd64494e482 Mon Sep 17 00:00:00 2001 From: yiqi Date: Mon, 30 Aug 2021 20:25:03 +0800 Subject: [PATCH 39/70] Add basic auth to AddPeer & RemovePeer. --- AElf.Client.Test/ClientTest.cs | 11 +++--- AElf.Client/Service/AElfClient.cs | 7 ++-- AElf.Client/Service/HttpService.cs | 53 +++++++++++++++++++--------- AElf.Client/Service/NetAppService.cs | 29 +++++++++++---- 4 files changed, 71 insertions(+), 29 deletions(-) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs index 66c3d79..a934323 100644 --- a/AElf.Client.Test/ClientTest.cs +++ b/AElf.Client.Test/ClientTest.cs @@ -25,7 +25,7 @@ namespace AElf.Client.Test { public class ClientTest { - private const string BaseUrl = "Http://127.0.0.1:8001"; + private const string BaseUrl = "http://192.168.196.116:8000"; private string _genesisAddress; private string GenesisAddress => GetGenesisContractAddress(); @@ -40,10 +40,13 @@ public class ClientTest private AElfClient Client { get; } private readonly ITestOutputHelper _testOutputHelper; + private const string UserName = "test1"; + private const string Password = "test"; + public ClientTest(ITestOutputHelper testOutputHelper) { _testOutputHelper = testOutputHelper; - Client = new AElfClient(BaseUrl); + Client = new AElfClient(BaseUrl, userName: UserName, password: Password); // To get address from privateKey.s _address = Client.GetAddressFromPrivateKey(PrivateKey); @@ -132,7 +135,7 @@ public async Task AddPeer_Test() // add ipAddress var addressToAdd = "192.168.199.122:7003"; - var addSuccess = await Client.AddPeerAsync(addressToAdd); + var addSuccess = await Client.AddPeerAsync(addressToAdd, UserName, Password); addSuccess.ShouldBeTrue(); _testOutputHelper.WriteLine($"Added ipAddress: {addressToAdd}"); } @@ -144,7 +147,7 @@ public async Task RemovePeer_Test() peers.ShouldNotBeEmpty(); var peerToRemoveAddress = peers[0].IpAddress; - var removeSuccess = await Client.RemovePeerAsync(peerToRemoveAddress); + var removeSuccess = await Client.RemovePeerAsync(peerToRemoveAddress, UserName, Password); Assert.True(removeSuccess); _testOutputHelper.WriteLine($"Removed ipAddress: {peerToRemoveAddress}"); } diff --git a/AElf.Client/Service/AElfClient.cs b/AElf.Client/Service/AElfClient.cs index e9637a8..92c46fb 100644 --- a/AElf.Client/Service/AElfClient.cs +++ b/AElf.Client/Service/AElfClient.cs @@ -27,6 +27,8 @@ public partial class AElfClient : IClientService { private readonly IHttpService _httpService; private string _baseUrl; + private readonly string _userName; + private readonly string _password; public string BaseUrl { @@ -36,11 +38,12 @@ public string BaseUrl private const string ExamplePrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; - public AElfClient(string baseUrl, int timeOut = 60) + public AElfClient(string baseUrl, int timeOut = 60, string userName = null, string password = null) { _httpService = new HttpService(timeOut); _baseUrl = baseUrl; - + _userName = userName; + _password = password; } /// diff --git a/AElf.Client/Service/HttpService.cs b/AElf.Client/Service/HttpService.cs index 03e9da1..4cde237 100644 --- a/AElf.Client/Service/HttpService.cs +++ b/AElf.Client/Service/HttpService.cs @@ -16,10 +16,12 @@ Task GetResponseAsync(string url, string version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK); Task PostResponseAsync(string url, Dictionary parameters, - string version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK); + string version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null); Task DeleteResponseAsObjectAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK); + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null); } public class HttpService : IHttpService @@ -57,13 +59,16 @@ public async Task GetResponseAsync(string url, string version = null, /// /// /// + /// /// /// public async Task PostResponseAsync(string url, Dictionary parameters, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) { - var response = await PostResponseAsStringAsync(url, parameters, version, expectedStatusCode); + var response = await PostResponseAsStringAsync(url, parameters, version, expectedStatusCode, + authenticationHeaderValue); return JsonConvert.DeserializeObject(response, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() @@ -80,9 +85,11 @@ public async Task PostResponseAsync(string url, Dictionary /// /// public async Task DeleteResponseAsObjectAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) { - var response = await DeleteResponseAsStringAsync(url, version, expectedStatusCode); + var response = + await DeleteResponseAsStringAsync(url, version, expectedStatusCode, authenticationHeaderValue); return JsonConvert.DeserializeObject(response, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() @@ -109,8 +116,7 @@ private async Task GetResponseAsync(string url, string vers var response = await client.GetAsync(url); if (response.StatusCode == expectedStatusCode) return response; - var message = await response.Content.ReadAsStringAsync(); - throw new AElfClientException(message); + throw new AElfClientException(response.ToString()); } catch (Exception ex) { @@ -123,20 +129,28 @@ private async Task GetResponseAsync(string url, string vers #region PostResponse private async Task PostResponseAsStringAsync(string url, Dictionary parameters, - string version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + string version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) { - var response = await PostResponseAsync(url, parameters, version, true, expectedStatusCode); + var response = await PostResponseAsync(url, parameters, version, true, expectedStatusCode, + authenticationHeaderValue); return await response.Content.ReadAsStringAsync(); } private async Task PostResponseAsync(string url, Dictionary parameters, string version = null, bool useApplicationJson = false, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) { version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; var client = GetHttpClient(version); + if (authenticationHeaderValue != null) + { + client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; + } + HttpContent content; if (useApplicationJson) { @@ -171,24 +185,31 @@ private async Task PostResponseAsync(string url, #region DeleteResponse private async Task DeleteResponseAsStringAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) { - var response = await DeleteResponseAsync(url, version, expectedStatusCode); + var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); return await response.Content.ReadAsStringAsync(); } private async Task DeleteResponseAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) { version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; var client = GetHttpClient(version); + + if (authenticationHeaderValue != null) + { + client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; + } + try { var response = await client.DeleteAsync(url); if (response.StatusCode == expectedStatusCode) return response; - var message = await response.Content.ReadAsStringAsync(); - throw new AElfClientException(message); + throw new AElfClientException(response.ToString()); } catch (Exception ex) { diff --git a/AElf.Client/Service/NetAppService.cs b/AElf.Client/Service/NetAppService.cs index f9e928c..22a7baa 100644 --- a/AElf.Client/Service/NetAppService.cs +++ b/AElf.Client/Service/NetAppService.cs @@ -1,4 +1,7 @@ +using System; using System.Collections.Generic; +using System.Net.Http.Headers; +using System.Text; using System.Threading.Tasks; using AElf.Client.Dto; using AElf.Client.Helper; @@ -7,9 +10,9 @@ namespace AElf.Client.Service { public interface INetAppService { - Task AddPeerAsync(string ipAddress); + Task AddPeerAsync(string ipAddress, string userName, string password); - Task RemovePeerAsync(string ipAddress); + Task RemovePeerAsync(string ipAddress, string userName, string password); Task> GetPeersAsync(bool withMetrics); @@ -22,8 +25,10 @@ public partial class AElfClient : INetAppService /// Attempt to add a node to the connected network nodes.Input parameter contains the ipAddress of the node. /// /// + /// + /// /// Add successfully or not - public async Task AddPeerAsync(string ipAddress) + public async Task AddPeerAsync(string ipAddress, string userName, string password) { if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) { @@ -36,23 +41,27 @@ public async Task AddPeerAsync(string ipAddress) {"address", endpoint.ToString()} }; - return await _httpService.PostResponseAsync(url, parameters); + return await _httpService.PostResponseAsync(url, parameters, + authenticationHeaderValue: GetAuthenticationHeaderValue()); } /// /// Attempt to remove a node from the connected network nodes by given the ipAddress. /// /// + /// + /// /// Delete successfully or not - public async Task RemovePeerAsync(string ipAddress) + public async Task RemovePeerAsync(string ipAddress, string userName, string password) { if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) { return false; } - + var url = GetRequestUrl(_baseUrl, $"api/net/peer?address={endpoint}"); - return await _httpService.DeleteResponseAsObjectAsync(url); + return await _httpService.DeleteResponseAsObjectAsync(url, + authenticationHeaderValue: GetAuthenticationHeaderValue()); } /// @@ -75,5 +84,11 @@ public async Task GetNetworkInfoAsync() var url = GetRequestUrl(_baseUrl, "api/net/networkInfo"); return await _httpService.GetResponseAsync(url); } + + private AuthenticationHeaderValue GetAuthenticationHeaderValue() + { + var byteArray = Encoding.ASCII.GetBytes($"{_userName}:{_password}"); + return new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); + } } } \ No newline at end of file From 089c713013971b5218af1fa63a1431b841cc8180 Mon Sep 17 00:00:00 2001 From: yiqi Date: Sun, 22 May 2022 01:35:17 +0800 Subject: [PATCH 40/70] Initial refactor of AElf.Client: AElfClientBuilder, TransactionBuilder, AElfCLientModule, AElfClientProvider, AElfClientService. --- all.sln | 53 ++ examples/AEDPoSViewer/AEDPoSViewer.csproj | 14 + examples/AEDPoSViewer/Program.cs | 23 + examples/ElectionViewer/ElectionViewer.csproj | 10 + examples/ElectionViewer/Program.cs | 3 + examples/TokenManager/Program.cs | 3 + examples/TokenManager/TokenManager.csproj | 10 + protobuf/aelf/core.proto | 147 ++++ protobuf/aelf/options.proto | 38 + .../AElf.Client.Protobuf.csproj | 39 + src/AElf.Client.Protobuf/Protobuf/acs0.proto | 234 ++++++ src/AElf.Client.Protobuf/Protobuf/acs1.proto | 53 ++ src/AElf.Client.Protobuf/Protobuf/acs10.proto | 80 ++ src/AElf.Client.Protobuf/Protobuf/acs11.proto | 31 + src/AElf.Client.Protobuf/Protobuf/acs2.proto | 30 + src/AElf.Client.Protobuf/Protobuf/acs3.proto | 207 +++++ src/AElf.Client.Protobuf/Protobuf/acs4.proto | 70 ++ src/AElf.Client.Protobuf/Protobuf/acs5.proto | 51 ++ src/AElf.Client.Protobuf/Protobuf/acs6.proto | 22 + src/AElf.Client.Protobuf/Protobuf/acs7.proto | 292 +++++++ src/AElf.Client.Protobuf/Protobuf/acs8.proto | 35 + src/AElf.Client.Protobuf/Protobuf/acs9.proto | 52 ++ .../Protobuf/aedpos_contract.proto | 440 +++++++++++ .../Protobuf/aelf/core.proto | 147 ++++ .../Protobuf/aelf/options.proto | 38 + .../Protobuf/association_contract.proto | 144 ++++ .../Protobuf/authority_info.proto | 10 + .../Protobuf/basic_contract_zero.proto | 71 ++ .../Protobuf/configuration_contract.proto | 52 ++ .../Protobuf/cross_chain_contract.proto | 266 +++++++ .../Protobuf/economic_contract.proto | 62 ++ .../Protobuf/election_contract.proto | 522 +++++++++++++ .../Protobuf/kernel.proto | 183 +++++ .../Protobuf/parliament_contract.proto | 148 ++++ .../Protobuf/profit_contract.proto | 370 +++++++++ .../Protobuf/referendum_contract.proto | 129 +++ .../Protobuf/token_contract.proto | 739 ++++++++++++++++++ .../Protobuf/token_converter_contract.proto | 193 +++++ .../Protobuf/token_holder_contract.proto | 132 ++++ .../Protobuf/transaction_fee.proto | 47 ++ .../Protobuf/treasury_contract.proto | 149 ++++ .../Protobuf/vote_contract.proto | 311 ++++++++ src/AElf.Client/AElf.Client.csproj | 19 + src/AElf.Client/AElfClient.Block.cs | 44 ++ src/AElf.Client/AElfClient.Chain.cs | 69 ++ src/AElf.Client/AElfClient.Client.cs | 249 ++++++ src/AElf.Client/AElfClient.Net.cs | 80 ++ src/AElf.Client/AElfClient.Transaction.cs | 165 ++++ src/AElf.Client/AElfClient.cs | 38 + src/AElf.Client/AElfClientBuilder.cs | 65 ++ src/AElf.Client/AElfClientConstants.cs | 13 + src/AElf.Client/AElfClientModule.cs | 17 + src/AElf.Client/AElfClientService.cs | 21 + src/AElf.Client/Dto/BlockBodyDto.cs | 8 + src/AElf.Client/Dto/BlockDto.cs | 10 + src/AElf.Client/Dto/BlockHeaderDto.cs | 24 + src/AElf.Client/Dto/ChainStatusDto.cs | 26 + .../Dto/CreateRawTransactionInput.cs | 78 ++ .../Dto/CreateRawTransactionOutput.cs | 6 + .../Dto/ExecuteRawTransactionDto.cs | 14 + src/AElf.Client/Dto/ExecuteTransactionDto.cs | 9 + src/AElf.Client/Dto/LogEventDto.cs | 12 + src/AElf.Client/Dto/MerklePathDto.cs | 12 + src/AElf.Client/Dto/NetworkInfoOutput.cs | 19 + src/AElf.Client/Dto/PeerDto.cs | 22 + .../Dto/SendRawTransactionInput.cs | 19 + .../Dto/SendRawTransactionOutput.cs | 8 + src/AElf.Client/Dto/SendTransactionInput.cs | 9 + src/AElf.Client/Dto/SendTransactionOutput.cs | 6 + src/AElf.Client/Dto/SendTransactionsInput.cs | 9 + src/AElf.Client/Dto/TaskQueueInfoDto.cs | 8 + src/AElf.Client/Dto/TransactionDto.cs | 18 + .../Dto/TransactionPoolStatusOutput.cs | 7 + src/AElf.Client/Dto/TransactionResultDto.cs | 22 + src/AElf.Client/EndpointType.cs | 10 + .../Exception/AElfClientException.cs | 9 + src/AElf.Client/Exception/Error.cs | 35 + .../Extensions/StringExtensions.cs | 14 + src/AElf.Client/GlobalUsings.cs | 1 + src/AElf.Client/Helper/EndpointHelper.cs | 95 +++ src/AElf.Client/IAElfClientProvider.cs | 66 ++ src/AElf.Client/IAElfClientService.cs | 6 + src/AElf.Client/Model/KeyPairInfo.cs | 9 + src/AElf.Client/Options/AElfAccountOptions.cs | 13 + src/AElf.Client/Options/AElfClientOptions.cs | 14 + src/AElf.Client/Services/HttpService.cs | 215 +++++ src/AElf.Client/Services/IBlockAppService.cs | 12 + src/AElf.Client/Services/IChainAppService.cs | 15 + src/AElf.Client/Services/IClientService.cs | 13 + src/AElf.Client/Services/INetAppService.cs | 14 + .../Services/ITransactionAppService.cs | 27 + src/AElf.Client/TransactionBuilder.cs | 60 ++ 92 files changed, 7404 insertions(+) create mode 100644 all.sln create mode 100644 examples/AEDPoSViewer/AEDPoSViewer.csproj create mode 100644 examples/AEDPoSViewer/Program.cs create mode 100644 examples/ElectionViewer/ElectionViewer.csproj create mode 100644 examples/ElectionViewer/Program.cs create mode 100644 examples/TokenManager/Program.cs create mode 100644 examples/TokenManager/TokenManager.csproj create mode 100644 protobuf/aelf/core.proto create mode 100644 protobuf/aelf/options.proto create mode 100644 src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs0.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs1.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs10.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs11.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs2.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs3.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs4.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs5.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs6.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs7.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs8.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/acs9.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/aedpos_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/aelf/core.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/aelf/options.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/association_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/authority_info.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/basic_contract_zero.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/configuration_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/cross_chain_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/economic_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/election_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/kernel.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/parliament_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/profit_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/referendum_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/token_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/token_converter_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/token_holder_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/transaction_fee.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/treasury_contract.proto create mode 100644 src/AElf.Client.Protobuf/Protobuf/vote_contract.proto create mode 100644 src/AElf.Client/AElf.Client.csproj create mode 100644 src/AElf.Client/AElfClient.Block.cs create mode 100644 src/AElf.Client/AElfClient.Chain.cs create mode 100644 src/AElf.Client/AElfClient.Client.cs create mode 100644 src/AElf.Client/AElfClient.Net.cs create mode 100644 src/AElf.Client/AElfClient.Transaction.cs create mode 100644 src/AElf.Client/AElfClient.cs create mode 100644 src/AElf.Client/AElfClientBuilder.cs create mode 100644 src/AElf.Client/AElfClientConstants.cs create mode 100644 src/AElf.Client/AElfClientModule.cs create mode 100644 src/AElf.Client/AElfClientService.cs create mode 100644 src/AElf.Client/Dto/BlockBodyDto.cs create mode 100644 src/AElf.Client/Dto/BlockDto.cs create mode 100644 src/AElf.Client/Dto/BlockHeaderDto.cs create mode 100644 src/AElf.Client/Dto/ChainStatusDto.cs create mode 100644 src/AElf.Client/Dto/CreateRawTransactionInput.cs create mode 100644 src/AElf.Client/Dto/CreateRawTransactionOutput.cs create mode 100644 src/AElf.Client/Dto/ExecuteRawTransactionDto.cs create mode 100644 src/AElf.Client/Dto/ExecuteTransactionDto.cs create mode 100644 src/AElf.Client/Dto/LogEventDto.cs create mode 100644 src/AElf.Client/Dto/MerklePathDto.cs create mode 100644 src/AElf.Client/Dto/NetworkInfoOutput.cs create mode 100644 src/AElf.Client/Dto/PeerDto.cs create mode 100644 src/AElf.Client/Dto/SendRawTransactionInput.cs create mode 100644 src/AElf.Client/Dto/SendRawTransactionOutput.cs create mode 100644 src/AElf.Client/Dto/SendTransactionInput.cs create mode 100644 src/AElf.Client/Dto/SendTransactionOutput.cs create mode 100644 src/AElf.Client/Dto/SendTransactionsInput.cs create mode 100644 src/AElf.Client/Dto/TaskQueueInfoDto.cs create mode 100644 src/AElf.Client/Dto/TransactionDto.cs create mode 100644 src/AElf.Client/Dto/TransactionPoolStatusOutput.cs create mode 100644 src/AElf.Client/Dto/TransactionResultDto.cs create mode 100644 src/AElf.Client/EndpointType.cs create mode 100644 src/AElf.Client/Exception/AElfClientException.cs create mode 100644 src/AElf.Client/Exception/Error.cs create mode 100644 src/AElf.Client/Extensions/StringExtensions.cs create mode 100644 src/AElf.Client/GlobalUsings.cs create mode 100644 src/AElf.Client/Helper/EndpointHelper.cs create mode 100644 src/AElf.Client/IAElfClientProvider.cs create mode 100644 src/AElf.Client/IAElfClientService.cs create mode 100644 src/AElf.Client/Model/KeyPairInfo.cs create mode 100644 src/AElf.Client/Options/AElfAccountOptions.cs create mode 100644 src/AElf.Client/Options/AElfClientOptions.cs create mode 100644 src/AElf.Client/Services/HttpService.cs create mode 100644 src/AElf.Client/Services/IBlockAppService.cs create mode 100644 src/AElf.Client/Services/IChainAppService.cs create mode 100644 src/AElf.Client/Services/IClientService.cs create mode 100644 src/AElf.Client/Services/INetAppService.cs create mode 100644 src/AElf.Client/Services/ITransactionAppService.cs create mode 100644 src/AElf.Client/TransactionBuilder.cs diff --git a/all.sln b/all.sln new file mode 100644 index 0000000..c212fa2 --- /dev/null +++ b/all.sln @@ -0,0 +1,53 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{940361AC-2167-4D30-A4F6-9A543C608196}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{7CD2B508-C765-4720-B430-94E79135797A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{5D1BDC45-D6F1-4359-868B-CB85CEC4ABD8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Client", "src\AElf.Client\AElf.Client.csproj", "{1AE7844D-B4D9-4F5A-9D25-7E551B61138E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Client.Protobuf", "src\AElf.Client.Protobuf\AElf.Client.Protobuf.csproj", "{E7DF7523-2FB5-45B3-9EAA-9B759FDDC2EB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TokenManager", "examples\TokenManager\TokenManager.csproj", "{CA0B4594-2549-4DB1-9079-EA5FD739C6B6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ElectionViewer", "examples\ElectionViewer\ElectionViewer.csproj", "{E678AABE-AF7B-45F4-B931-CF0D77C5AECA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AEDPoSViewer", "examples\AEDPoSViewer\AEDPoSViewer.csproj", "{BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {1AE7844D-B4D9-4F5A-9D25-7E551B61138E} = {940361AC-2167-4D30-A4F6-9A543C608196} + {E7DF7523-2FB5-45B3-9EAA-9B759FDDC2EB} = {940361AC-2167-4D30-A4F6-9A543C608196} + {CA0B4594-2549-4DB1-9079-EA5FD739C6B6} = {5D1BDC45-D6F1-4359-868B-CB85CEC4ABD8} + {E678AABE-AF7B-45F4-B931-CF0D77C5AECA} = {5D1BDC45-D6F1-4359-868B-CB85CEC4ABD8} + {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729} = {5D1BDC45-D6F1-4359-868B-CB85CEC4ABD8} + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1AE7844D-B4D9-4F5A-9D25-7E551B61138E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1AE7844D-B4D9-4F5A-9D25-7E551B61138E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1AE7844D-B4D9-4F5A-9D25-7E551B61138E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1AE7844D-B4D9-4F5A-9D25-7E551B61138E}.Release|Any CPU.Build.0 = Release|Any CPU + {E7DF7523-2FB5-45B3-9EAA-9B759FDDC2EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7DF7523-2FB5-45B3-9EAA-9B759FDDC2EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7DF7523-2FB5-45B3-9EAA-9B759FDDC2EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7DF7523-2FB5-45B3-9EAA-9B759FDDC2EB}.Release|Any CPU.Build.0 = Release|Any CPU + {CA0B4594-2549-4DB1-9079-EA5FD739C6B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CA0B4594-2549-4DB1-9079-EA5FD739C6B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CA0B4594-2549-4DB1-9079-EA5FD739C6B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CA0B4594-2549-4DB1-9079-EA5FD739C6B6}.Release|Any CPU.Build.0 = Release|Any CPU + {E678AABE-AF7B-45F4-B931-CF0D77C5AECA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E678AABE-AF7B-45F4-B931-CF0D77C5AECA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E678AABE-AF7B-45F4-B931-CF0D77C5AECA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E678AABE-AF7B-45F4-B931-CF0D77C5AECA}.Release|Any CPU.Build.0 = Release|Any CPU + {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/examples/AEDPoSViewer/AEDPoSViewer.csproj b/examples/AEDPoSViewer/AEDPoSViewer.csproj new file mode 100644 index 0000000..c35049a --- /dev/null +++ b/examples/AEDPoSViewer/AEDPoSViewer.csproj @@ -0,0 +1,14 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + diff --git a/examples/AEDPoSViewer/Program.cs b/examples/AEDPoSViewer/Program.cs new file mode 100644 index 0000000..c55a16d --- /dev/null +++ b/examples/AEDPoSViewer/Program.cs @@ -0,0 +1,23 @@ +using AElf; +using AElf.Client; +using AElf.Client.Dto; +using AElf.Contracts.Consensus.AEDPoS; +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; + +var aelfClient = new AElfClientBuilder().UsePublicEndpoint(EndpointType.MainNetMainChain).Build(); +var tx = new TransactionBuilder(aelfClient) + .UsePrivateKey(AElfClientConstants.DefaultPrivateKey) + .UseSystemContract("AElf.ContractNames.Consensus") + .UseMethod("GetCurrentRoundInformation") + .UseParameter(new Empty()) + .Build(); + +var result = await aelfClient.ExecuteTransactionAsync(new ExecuteTransactionDto +{ + RawTransaction = tx.ToByteArray().ToHex() +}); + +var round = new Round(); +round.MergeFrom(ByteArrayHelper.HexStringToByteArray(result)); +Console.WriteLine(round); \ No newline at end of file diff --git a/examples/ElectionViewer/ElectionViewer.csproj b/examples/ElectionViewer/ElectionViewer.csproj new file mode 100644 index 0000000..b9de063 --- /dev/null +++ b/examples/ElectionViewer/ElectionViewer.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/examples/ElectionViewer/Program.cs b/examples/ElectionViewer/Program.cs new file mode 100644 index 0000000..e5dff12 --- /dev/null +++ b/examples/ElectionViewer/Program.cs @@ -0,0 +1,3 @@ +// See https://aka.ms/new-console-template for more information + +Console.WriteLine("Hello, World!"); \ No newline at end of file diff --git a/examples/TokenManager/Program.cs b/examples/TokenManager/Program.cs new file mode 100644 index 0000000..e5dff12 --- /dev/null +++ b/examples/TokenManager/Program.cs @@ -0,0 +1,3 @@ +// See https://aka.ms/new-console-template for more information + +Console.WriteLine("Hello, World!"); \ No newline at end of file diff --git a/examples/TokenManager/TokenManager.csproj b/examples/TokenManager/TokenManager.csproj new file mode 100644 index 0000000..b9de063 --- /dev/null +++ b/examples/TokenManager/TokenManager.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/protobuf/aelf/core.proto b/protobuf/aelf/core.proto new file mode 100644 index 0000000..e410996 --- /dev/null +++ b/protobuf/aelf/core.proto @@ -0,0 +1,147 @@ +syntax = "proto3"; + +package aelf; + +option csharp_namespace = "AElf.Types"; + +message Transaction { + // The address of the sender of the transaction. + Address from = 1; + // The address of the contract when calling a contract. + Address to = 2; + // The height of the referenced block hash. + int64 ref_block_number = 3; + // The first four bytes of the referenced block hash. + bytes ref_block_prefix = 4; + // The name of a method in the smart contract at the To address. + string method_name = 5; + // The parameters to pass to the smart contract method. + bytes params = 6; + // When signing a transaction it’s actually a subset of the fields: from/to and the target method as well as + // the parameter that were given. It also contains the reference block number and prefix. + bytes signature = 10000; +} + +message StatePath { + // The partial path of the state path. + repeated string parts = 1; +} + +message ScopedStatePath { + // The scope address, which will be the contract address. + Address address = 1; + // The path of contract state. + StatePath path = 2; +} + +enum TransactionResultStatus { + // The execution result of the transaction does not exist. + NOT_EXISTED = 0; + // The transaction is in the transaction pool waiting to be packaged. + PENDING = 1; + // Transaction execution failed. + FAILED = 2; + // The transaction was successfully executed and successfully packaged into a block. + MINED = 3; + // When executed in parallel, there are conflicts with other transactions. + CONFLICT = 4; + // The transaction is waiting for validation. + PENDING_VALIDATION = 5; + // Transaction validation failed. + NODE_VALIDATION_FAILED = 6; +} + +message TransactionResult { + // The transaction id. + Hash transaction_id = 1; + // The transaction result status. + TransactionResultStatus status = 2; + // The log events. + repeated LogEvent logs = 3; + // Bloom filter for transaction logs. A transaction log event can be defined in the contract and stored + // in the bloom filter after the transaction is executed. Through this filter, we can quickly search for + // and determine whether a log exists in the transaction result. + bytes bloom = 4; + // The return value of the transaction execution. + bytes return_value = 5; + // The height of the block hat packages the transaction. + int64 block_number = 6; + // The hash of the block hat packages the transaction. + Hash block_hash = 7; + // Failed execution error message. + string error = 10; +} + +message LogEvent { + // The contract address. + Address address = 1; + // The name of the log event. + string name = 2; + // The indexed data, used to calculate bloom. + repeated bytes indexed = 3; + // The non indexed data. + bytes non_indexed = 4; +} + +message SmartContractRegistration { + // The category of contract code(0: C#). + sint32 category = 1; + // The byte array of the contract code. + bytes code = 2; + // The hash of the contract code. + Hash code_hash = 3; + // Whether it is a system contract. + bool is_system_contract = 4; + // The version of the current contract. + int32 version = 5; +} + +message TransactionExecutingStateSet { + // The changed states. + map writes = 1; + // The read states. + map reads = 2; + // The deleted states. + map deletes = 3; +} + +message Address +{ + bytes value = 1; +} + +message Hash +{ + bytes value = 1; +} + +message SInt32Value +{ + sint32 value = 1; +} + +message SInt64Value +{ + sint64 value = 1; +} + +message MerklePath { + // The merkle path nodes. + repeated MerklePathNode merkle_path_nodes = 1; +} + +message MerklePathNode{ + // The node hash. + Hash hash = 1; + // Whether it is a left child node. + bool is_left_child_node = 2; +} + +message BinaryMerkleTree { + // The leaf nodes. + repeated Hash nodes = 1; + // The root node hash. + Hash root = 2; + // The count of leaf node. + int32 leaf_count = 3; +} \ No newline at end of file diff --git a/protobuf/aelf/options.proto b/protobuf/aelf/options.proto new file mode 100644 index 0000000..34058ba --- /dev/null +++ b/protobuf/aelf/options.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package aelf; + +import "google/protobuf/descriptor.proto"; + +option csharp_namespace = "AElf"; + +// All aelf custom options field numbers are like 50yxxx +// where y stands for the custom options type: +// 0 - FileOptions +// 1 - MessageOptions +// 2 - FieldOptions +// 3 - EnumOptions +// 4 - EnumValueOptions +// 5 - ServiceOptions +// 6 - MethodOptions + +extend google.protobuf.FileOptions { + string identity = 500001; +} + +extend google.protobuf.ServiceOptions { + repeated string base = 505001; + string csharp_state = 505030; +} + +extend google.protobuf.MethodOptions { + bool is_view = 506001; +} + +extend google.protobuf.MessageOptions { + bool is_event = 50100; +} + +extend google.protobuf.FieldOptions { + bool is_indexed = 502001; +} diff --git a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj new file mode 100644 index 0000000..2ea3a9c --- /dev/null +++ b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj @@ -0,0 +1,39 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + MSBuild:Compile + + + + diff --git a/src/AElf.Client.Protobuf/Protobuf/acs0.proto b/src/AElf.Client.Protobuf/Protobuf/acs0.proto new file mode 100644 index 0000000..84606e7 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs0.proto @@ -0,0 +1,234 @@ +/** + * AElf Standards ACS0(Contract Deployment Standard) + * + * Used to manage the deployment and update of contracts. + */ +syntax = "proto3"; + +package acs0; +option csharp_namespace = "AElf.Standards.ACS0"; + +import public "aelf/core.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +service ACS0 { + // Deploy a system smart contract on chain and return the address of the system contract deployed. + rpc DeploySystemSmartContract (SystemContractDeploymentInput) returns (aelf.Address) { + } + + // Deploy a smart contract on chain and return the address of the contract deployed. + rpc DeploySmartContract (ContractDeploymentInput) returns (aelf.Address) { + } + + // Update a smart contract on chain. + rpc UpdateSmartContract (ContractUpdateInput) returns (aelf.Address) { + } + + // Create a proposal to deploy a new contract and returns the id of the proposed contract. + rpc ProposeNewContract (ContractDeploymentInput) returns (aelf.Hash) { + } + + // Create a proposal to check the code of a contract and return the id of the proposed contract. + rpc ProposeContractCodeCheck (ContractCodeCheckInput) returns (aelf.Hash) { + } + + // Create a proposal to update the specified contract + // and return the id of the proposed contract. + rpc ProposeUpdateContract (ContractUpdateInput) returns (aelf.Hash) { + } + + // Release the contract proposal which has been approved. + rpc ReleaseApprovedContract (ReleaseContractInput) returns (google.protobuf.Empty) { + } + + // Release the proposal which has passed the code check. + rpc ReleaseCodeCheckedContract (ReleaseContractInput) returns (google.protobuf.Empty) { + } + + // Validate whether the input system contract exists. + rpc ValidateSystemContractAddress(ValidateSystemContractAddressInput) returns (google.protobuf.Empty){ + } + + // Set authority of contract deployment. + rpc SetContractProposerRequiredState (google.protobuf.BoolValue) returns (google.protobuf.Empty) { + } + + // Get the current serial number of genesis contract + // (corresponds to the serial number that will be given to the next deployed contract). + rpc CurrentContractSerialNumber (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get detailed information about the specified contract. + rpc GetContractInfo (aelf.Address) returns (ContractInfo) { + option (aelf.is_view) = true; + } + + // Get author of the specified contract. + rpc GetContractAuthor (aelf.Address) returns (aelf.Address) { + option (aelf.is_view) = true; + } + + // Get the code hash of the contract about the specified address. + rpc GetContractHash (aelf.Address) returns (aelf.Hash) { + option (aelf.is_view) = true; + } + + // Get the address of a system contract by its name. + rpc GetContractAddressByName (aelf.Hash) returns (aelf.Address) { + option (aelf.is_view) = true; + } + + // Get the registration of a smart contract by its address. + rpc GetSmartContractRegistrationByAddress (aelf.Address) returns (aelf.SmartContractRegistration) { + option (aelf.is_view) = true; + } + + // Get the registration of a smart contract by code hash. + rpc GetSmartContractRegistrationByCodeHash (aelf.Hash) returns (aelf.SmartContractRegistration) { + option (aelf.is_view) = true; + } + + rpc GetContractCodeHashListByDeployingBlockHeight (google.protobuf.Int64Value) returns (ContractCodeHashList) { + option (aelf.is_view) = true; + } +} + +message ContractInfo +{ + // The serial number of the contract. + int64 serial_number = 1; + // The author of the contract, this is the person who deployed the contract. + aelf.Address author = 2; + // The category of contract code(0: C#). + sint32 category = 3; + // The hash of the contract code. + aelf.Hash code_hash = 4; + // Whether it is a system contract. + bool is_system_contract = 5; + // The version of the current contract. + int32 version = 6; +} + +message ContractDeploymentInput { + // The category of contract code(0: C#). + sint32 category = 1; + // The byte array of the contract code. + bytes code = 2; +} + +message SystemContractDeploymentInput { + message SystemTransactionMethodCall { + // The method name of system transaction. + string method_name = 1; + // The params of system transaction method. + bytes params = 2; + } + message SystemTransactionMethodCallList { + // The list of system transactions. + repeated SystemTransactionMethodCall value = 1; + } + // The category of contract code(0: C#). + sint32 category = 1; + // The byte array of the contract code. + bytes code = 2; + // The name of the contract. It has to be unique. + aelf.Hash name = 3; + // An initial list of transactions for the system contract, + // which is executed in sequence when the contract is deployed. + SystemTransactionMethodCallList transaction_method_call_list = 4; +} + +message ContractUpdateInput { + // The contract address that needs to be updated. + aelf.Address address = 1; + // The byte array of the new contract code. + bytes code = 2; +} + +message ContractCodeCheckInput{ + // The byte array of the contract code to be checked. + bytes contract_input = 1; + // Whether the input contract is to be deployed or updated. + bool is_contract_deployment = 2; + // Method to call after code check complete(DeploySmartContract or UpdateSmartContract). + string code_check_release_method = 3; + // The id of the proposed contract. + aelf.Hash proposed_contract_input_hash = 4; + // The category of contract code(0: C#). + sint32 category = 5; + // Indicates if the contract is the system contract. + bool is_system_contract = 6; +} + +message ContractProposed +{ + option (aelf.is_event) = true; + // The id of the proposed contract. + aelf.Hash proposed_contract_input_hash = 1; +} + +message ContractDeployed +{ + option (aelf.is_event) = true; + // The author of the contract, this is the person who deployed the contract. + aelf.Address author = 1 [(aelf.is_indexed) = true]; + // The hash of the contract code. + aelf.Hash code_hash = 2 [(aelf.is_indexed) = true]; + // The address of the contract. + aelf.Address address = 3; + // The version of the current contract. + int32 version = 4; + // The name of the contract. It has to be unique. + aelf.Hash Name = 5; +} + +message CodeCheckRequired +{ + option (aelf.is_event) = true; + // The byte array of the contract code. + bytes code = 1; + // The id of the proposed contract. + aelf.Hash proposed_contract_input_hash = 2; + // The category of contract code(0: C#). + sint32 category = 3; + // Indicates if the contract is the system contract. + bool is_system_contract = 4; +} + +message CodeUpdated +{ + option (aelf.is_event) = true; + // The address of the updated contract. + aelf.Address address = 1 [(aelf.is_indexed) = true]; + // The byte array of the old contract code. + aelf.Hash old_code_hash = 2; + // The byte array of the new contract code. + aelf.Hash new_code_hash = 3; + // The version of the current contract. + int32 version = 4; +} + +message ValidateSystemContractAddressInput { + // The name hash of the contract. + aelf.Hash system_contract_hash_name = 1; + // The address of the contract. + aelf.Address address = 2; +} + +message ReleaseContractInput { + // The hash of the proposal. + aelf.Hash proposal_id = 1; + // The id of the proposed contract. + aelf.Hash proposed_contract_input_hash = 2; +} + +message ContractCodeHashList { + repeated aelf.Hash value = 1; +} + +message ContractCodeHashMap { + map value = 1; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs1.proto b/src/AElf.Client.Protobuf/Protobuf/acs1.proto new file mode 100644 index 0000000..4894a1b --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs1.proto @@ -0,0 +1,53 @@ +/** + * AElf Standards ACS1(Transaction Fee Standard) + * + * Used to manage the transaction fee. + */ +syntax = "proto3"; + +package acs1; + +import public "aelf/options.proto"; +import public "google/protobuf/empty.proto"; +import public "google/protobuf/wrappers.proto"; +import "aelf/core.proto"; +import "authority_info.proto"; + +option (aelf.identity) = "acs1"; +option csharp_namespace = "AElf.Standards.ACS1"; + +service MethodFeeProviderContract { + + // Set the method fees for the specified method. Note that this will override all fees of the method. + rpc SetMethodFee (MethodFees) returns (google.protobuf.Empty) { + } + + // Change the method fee controller, the default is parliament and default organization. + rpc ChangeMethodFeeController (AuthorityInfo) returns (google.protobuf.Empty) { + } + + // Query method fee information by method name. + rpc GetMethodFee (google.protobuf.StringValue) returns (MethodFees) { + option (aelf.is_view) = true; + } + + // Query the method fee controller. + rpc GetMethodFeeController (google.protobuf.Empty) returns (AuthorityInfo) { + option (aelf.is_view) = true; + } +} + +message MethodFees { + // The name of the method to be charged. + string method_name = 1; + // List of fees to be charged. + repeated MethodFee fees = 2; + bool is_size_fee_free = 3;// Optional based on the implementation of SetMethodFee method. +} + +message MethodFee { + // The token symbol of the method fee. + string symbol = 1; + // The amount of fees to be charged. + int64 basic_fee = 2; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs10.proto b/src/AElf.Client.Protobuf/Protobuf/acs10.proto new file mode 100644 index 0000000..0b6f324 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs10.proto @@ -0,0 +1,80 @@ +/** + * AElf Standards ACS10(Dividend Pool Standard) + * + * Used to construct a dividend pool in the contract. + */ +syntax = "proto3"; + +package acs10; + +import public "aelf/options.proto"; +import public "google/protobuf/empty.proto"; +import public "google/protobuf/wrappers.proto"; +import "aelf/core.proto"; + +option (aelf.identity) = "acs10"; +option csharp_namespace = "AElf.Standards.ACS10"; + +service DividendPoolContract { + // Donates tokens from the caller to the treasury. If the tokens are not native tokens in the current chain, + // they will be first converted to the native token. + rpc Donate (DonateInput) returns (google.protobuf.Empty) { + } + + // Release dividend pool according the period number. + rpc Release (ReleaseInput) returns (google.protobuf.Empty) { + } + + // Set the token symbols dividend pool supports. + rpc SetSymbolList (SymbolList) returns (google.protobuf.Empty) { + } + + // Query the token symbols dividend pool supports. + rpc GetSymbolList (google.protobuf.Empty) returns (SymbolList) { + option (aelf.is_view) = true; + } + + // Query the balance of undistributed tokens whose symbols are included in the symbol list. + rpc GetUndistributedDividends (google.protobuf.Empty) returns (Dividends) { + option (aelf.is_view) = true; + } + + // Query the dividend information according to the height. + rpc GetDividends (google.protobuf.Int64Value) returns (Dividends) { + option (aelf.is_view) = true; + } +} + +message DonateInput { + // The token symbol to donate. + string symbol = 1; + // The amount to donate. + int64 amount = 2; +} + +message ReleaseInput { + // The period number to release. + int64 period_number = 1; +} + +message SymbolList { + // The token symbol list. + repeated string value = 1; +} + +message Dividends { + // The dividends, symbol -> amount. + map value = 1; +} + +message DonationReceived { + option (aelf.is_event) = true; + // The address of donors. + aelf.Address from = 1; + // The address of dividend pool. + aelf.Address pool_contract = 2; + // The token symbol Donated. + string symbol = 3; + // The amount Donated. + int64 amount = 4; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs11.proto b/src/AElf.Client.Protobuf/Protobuf/acs11.proto new file mode 100644 index 0000000..d7708a7 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs11.proto @@ -0,0 +1,31 @@ +/** + * AElf Standards ACS11(Consensus Standard) + * + * Used to customize consensus mechanisms for cross chain. + */ +syntax = "proto3"; + +package acs11; +import "aelf/options.proto"; +import "aelf/core.proto"; +import "google/protobuf/wrappers.proto"; +import "google/protobuf/empty.proto"; + +option (aelf.identity) = "acs11"; +option csharp_namespace = "AElf.Standards.ACS11"; + +service CrossChainInteractionContract { + // Update the consensus information of the side chain. + rpc UpdateInformationFromCrossChain (google.protobuf.BytesValue) returns (google.protobuf.Empty) { + } + + // Get the current miner list and consensus round information. + rpc GetChainInitializationInformation (google.protobuf.BytesValue) returns (google.protobuf.BytesValue) { + option (aelf.is_view) = true; + } + + // Verify that the input address is the current miner. + rpc CheckCrossChainIndexingPermission (aelf.Address) returns (google.protobuf.BoolValue) { + option (aelf.is_view) = true; + } +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs2.proto b/src/AElf.Client.Protobuf/Protobuf/acs2.proto new file mode 100644 index 0000000..637e66e --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs2.proto @@ -0,0 +1,30 @@ +/** + * AElf Standards ACS2(Parallel Execution Standard) + * + * Used to provide information for parallel execution of transactions. + */ +syntax = "proto3"; + +package acs2; + +import "aelf/core.proto"; +import "aelf/options.proto"; + +option (aelf.identity) = "acs2"; +option csharp_namespace = "AElf.Standards.ACS2"; + +service ACS2Base { + // Gets the resource information that the transaction execution depends on. + rpc GetResourceInfo (aelf.Transaction) returns (ResourceInfo) { + option (aelf.is_view) = true; + } +} + +message ResourceInfo { + // The state path that depends on when writing. + repeated aelf.ScopedStatePath write_paths = 1; + // The state path that depends on when reading. + repeated aelf.ScopedStatePath read_paths = 2; + // Whether the transaction is not executed in parallel. + bool non_parallelizable = 3; +} diff --git a/src/AElf.Client.Protobuf/Protobuf/acs3.proto b/src/AElf.Client.Protobuf/Protobuf/acs3.proto new file mode 100644 index 0000000..65ee66e --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs3.proto @@ -0,0 +1,207 @@ +/** + * AElf Standards ACS3(Contract Proposal Standard) + * + * Used for governance through proposals. + */ +syntax = "proto3"; + +package acs3; + +import public "aelf/core.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import public "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; + +option (aelf.identity) = "acs3"; +option csharp_namespace = "AElf.Standards.ACS3"; + +service AuthorizationContract { + // Create a proposal for which organization members can vote. + // When the proposal is released, a transaction will be sent to the specified contract. + // Return id of the newly created proposal. + rpc CreateProposal (CreateProposalInput) returns (aelf.Hash) { + } + + // Approve a proposal according to the proposal ID. + rpc Approve (aelf.Hash) returns (google.protobuf.Empty) { + } + + // Reject a proposal according to the proposal ID. + rpc Reject(aelf.Hash) returns (google.protobuf.Empty) { + } + + // Abstain a proposal according to the proposal ID. + rpc Abstain(aelf.Hash) returns (google.protobuf.Empty){ + } + + // Release a proposal according to the proposal ID and send a transaction to the specified contract. + rpc Release(aelf.Hash) returns (google.protobuf.Empty){ + } + + // Change the thresholds associated with proposals. + // All fields will be overwritten by the input value and this will affect all current proposals of the organization. + // Note: only the organization can execute this through a proposal. + rpc ChangeOrganizationThreshold(ProposalReleaseThreshold)returns(google.protobuf.Empty) { + } + + // Change the white list of organization proposer. + // This method overrides the list of whitelisted proposers. + rpc ChangeOrganizationProposerWhiteList(ProposerWhiteList) returns (google.protobuf.Empty){ + } + + // Create a proposal by system contracts, + // and return id of the newly created proposal. + rpc CreateProposalBySystemContract(CreateProposalBySystemContractInput) returns (aelf.Hash){ + } + + // Remove the specified proposal. If the proposal is in effect, the cleanup fails. + rpc ClearProposal(aelf.Hash) returns (google.protobuf.Empty){ + } + + // Get the proposal according to the proposal ID. + rpc GetProposal(aelf.Hash) returns (ProposalOutput) { + option (aelf.is_view) = true; + } + + // Check the existence of an organization. + rpc ValidateOrganizationExist(aelf.Address) returns (google.protobuf.BoolValue){ + option (aelf.is_view) = true; + } + + // Check if the proposer is whitelisted. + rpc ValidateProposerInWhiteList(ValidateProposerInWhiteListInput) returns (google.protobuf.BoolValue){ + option (aelf.is_view) = true; + } +} + +message CreateProposalInput { + // The name of the method to call after release. + string contract_method_name = 1; + // The address of the contract to call after release. + aelf.Address to_address = 2; + // The parameter of the method to be called after the release. + bytes params = 3; + // The timestamp at which this proposal will expire. + google.protobuf.Timestamp expired_time = 4; + // The address of the organization. + aelf.Address organization_address = 5; + // Url is used for proposal describing. + string proposal_description_url = 6; + // The token is for proposal id generation and with this token, proposal id can be calculated before proposing. + aelf.Hash token = 7; +} + +message ProposalOutput { + // The id of the proposal. + aelf.Hash proposal_id = 1; + // The method that this proposal will call when being released. + string contract_method_name = 2; + // The address of the target contract. + aelf.Address to_address = 3; + // The parameters of the release transaction. + bytes params = 4; + // The date at which this proposal will expire. + google.protobuf.Timestamp expired_time = 5; + // The address of this proposals organization. + aelf.Address organization_address = 6; + // The address of the proposer of this proposal. + aelf.Address proposer = 7; + // Indicates if this proposal is releasable. + bool to_be_released = 8; + // Approval count for this proposal. + int64 approval_count = 9; + // Rejection count for this proposal. + int64 rejection_count = 10; + // Abstention count for this proposal. + int64 abstention_count = 11; +} + +message ProposalReleaseThreshold { + // The value for the minimum approval threshold. + int64 minimal_approval_threshold = 1; + // The value for the maximal rejection threshold. + int64 maximal_rejection_threshold = 2; + // The value for the maximal abstention threshold. + int64 maximal_abstention_threshold = 3; + // The value for the minimal vote threshold. + int64 minimal_vote_threshold = 4; +} + +message ProposerWhiteList{ + // The address of the proposers + repeated aelf.Address proposers = 1; +} + +message OrganizationHashAddressPair{ + // The id of organization. + aelf.Hash organization_hash = 1; + // The address of organization. + aelf.Address organization_address = 2; +} + +message CreateProposalBySystemContractInput { + // The parameters of creating proposal. + acs3.CreateProposalInput proposal_input =1; + // The actor that trigger the call. + aelf.Address origin_proposer = 2; +} + +message ValidateProposerInWhiteListInput{ + // The address to search/check. + aelf.Address proposer = 1; + // The address of the organization. + aelf.Address organization_address = 2; +} + +message ProposalCreated{ + option (aelf.is_event) = true; + // The id of the created proposal. + aelf.Hash proposal_id = 1; + // The organization address of the created proposal. + aelf.Address organization_address=2 [(aelf.is_indexed) = true]; +} + +message ProposalReleased{ + option (aelf.is_event) = true; + // The id of the released proposal. + aelf.Hash proposal_id = 1; + // The organization address of the released proposal. + aelf.Address organization_address=2 [(aelf.is_indexed) = true]; +} + +message OrganizationCreated{ + option (aelf.is_event) = true; + // The address of the created organization. + aelf.Address organization_address = 1; +} + +message ReceiptCreated { + option (aelf.is_event) = true; + // The id of the proposal. + aelf.Hash proposal_id = 1; + // The sender address. + aelf.Address address = 2; + // The type of receipt(Approve, Reject or Abstain). + string receipt_type = 3; + // The timestamp of this method call. + google.protobuf.Timestamp time = 4; + // The address of the organization. + aelf.Address organization_address = 5 [(aelf.is_indexed) = true]; +} + +message OrganizationWhiteListChanged{ + option (aelf.is_event) = true; + // The organization address. + aelf.Address organization_address = 1; + // The new proposer whitelist. + ProposerWhiteList proposer_white_list = 2; +} + +message OrganizationThresholdChanged{ + option (aelf.is_event) = true; + // The organization address + aelf.Address organization_address = 1; + // The new release threshold. + ProposalReleaseThreshold proposer_release_threshold = 2; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs4.proto b/src/AElf.Client.Protobuf/Protobuf/acs4.proto new file mode 100644 index 0000000..0328f53 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs4.proto @@ -0,0 +1,70 @@ +/** + * AElf Standards ACS4(Consensus Standard) + * + * Used to customize consensus mechanisms. + */ +syntax = "proto3"; + +package acs4; + +import "aelf/options.proto"; +import "aelf/core.proto"; +import "google/protobuf/wrappers.proto"; +import "google/protobuf/timestamp.proto"; + +option (aelf.identity) = "acs4"; +option csharp_namespace = "AElf.Standards.ACS4"; + +service ConsensusContract { + // Generate a consensus command based on the consensus contract state and the input public key. + rpc GetConsensusCommand (google.protobuf.BytesValue) returns (ConsensusCommand) { + option (aelf.is_view) = true; + } + + // Generate consensus extra data when a block is generated. + rpc GetConsensusExtraData (google.protobuf.BytesValue) returns (google.protobuf.BytesValue) { + option (aelf.is_view) = true; + } + + // Generate consensus system transactions when a block is generated. + // Each block will contain only one consensus transaction, which is used to write the latest consensus information + // to the State database. + rpc GenerateConsensusTransactions (google.protobuf.BytesValue) returns (TransactionList) { + option (aelf.is_view) = true; + } + + // Before executing the block, verify that the consensus information in the block header is correct. + rpc ValidateConsensusBeforeExecution (google.protobuf.BytesValue) returns (ValidationResult) { + option (aelf.is_view) = true; + } + + // After executing the block, verify that the state information written to the consensus is correct. + rpc ValidateConsensusAfterExecution (google.protobuf.BytesValue) returns (ValidationResult) { + option (aelf.is_view) = true; + } +} + +message ConsensusCommand { + // Time limit of mining next block. + int32 limit_milliseconds_of_mining_block = 1; + // Context of Hint is diverse according to the consensus protocol we choose, so we use bytes. + bytes hint = 2; + // The time of arrange mining. + google.protobuf.Timestamp arranged_mining_time = 3; + // The expiration time of mining. + google.protobuf.Timestamp mining_due_time = 4; +} + +message ValidationResult { + // Is successful. + bool success = 1; + // The error message. + string message = 2; + // Whether to trigger mining again. + bool is_re_trigger = 3; +} + +message TransactionList { + // Consensus system transactions. + repeated aelf.Transaction transactions = 1; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs5.proto b/src/AElf.Client.Protobuf/Protobuf/acs5.proto new file mode 100644 index 0000000..f6de21e --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs5.proto @@ -0,0 +1,51 @@ +/** + * AElf Standards ACS5(Method Calling Threshold Contract Standard) + * + * To avoid DDOS attacks, all contracts should theoretically implement AElf Standards ACS5, + * setting a threshold for expensive methods. There are two types of call thresholds: check balance only, + * and check balance and allowance at the same time. + */ +syntax = "proto3"; + +package acs5; + +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +option (aelf.identity) = "acs5"; +option csharp_namespace = "AElf.Standards.ACS5"; + +service ThresholdSettingContract { + // Set the threshold for method calling. + rpc SetMethodCallingThreshold (SetMethodCallingThresholdInput) returns (google.protobuf.Empty) { + } + + // Get the threshold for method calling. + rpc GetMethodCallingThreshold (google.protobuf.StringValue) returns (MethodCallingThreshold) { + option (aelf.is_view) = true; + } +} + +message MethodCallingThreshold { + // The threshold for method calling, token symbol -> amount. + map symbol_to_amount = 1; + // The type of threshold check. + ThresholdCheckType threshold_check_type = 2; +} + +message SetMethodCallingThresholdInput { + // The method name to check. + string method = 1; + // The threshold for method calling, token symbol -> amount. + map symbol_to_amount = 2; + // The type of threshold check. + ThresholdCheckType threshold_check_type = 3; +} + +enum ThresholdCheckType { + // Check balance only. + BALANCE = 0; + // Check balance and allowance at the same time. + ALLOWANCE = 1; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs6.proto b/src/AElf.Client.Protobuf/Protobuf/acs6.proto new file mode 100644 index 0000000..f95ba5e --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs6.proto @@ -0,0 +1,22 @@ +/** + * AElf Standards ACS6(Random Number Standard) + * + * Used to generate random number. + */ +syntax = "proto3"; + +package acs6; + +import "aelf/options.proto"; +import "aelf/core.proto"; +import "google/protobuf/wrappers.proto"; + +option (aelf.identity) = "acs6"; +option csharp_namespace = "AElf.Standards.ACS6"; + +service RandomNumberProviderContract { + // Get random number according to block height. + rpc GetRandomBytes (google.protobuf.BytesValue) returns (google.protobuf.BytesValue) { + option (aelf.is_view) = true; + } +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs7.proto b/src/AElf.Client.Protobuf/Protobuf/acs7.proto new file mode 100644 index 0000000..2e9619d --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs7.proto @@ -0,0 +1,292 @@ +/** + * AElf Standards ACS7(Contract CrossChain Standard) + * + * ACS7 is for cross chain related contract implementation. + */ +syntax = "proto3"; + +package acs7; + +import public "aelf/core.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; +import public "google/protobuf/timestamp.proto"; + +option (aelf.identity) = "acs7"; +option csharp_namespace = "AElf.Standards.ACS7"; + +service ACS7 { + + // Propose once cross chain indexing. + rpc ProposeCrossChainIndexing(CrossChainBlockData) returns (google.protobuf.Empty) { + } + + // Release the proposed indexing if already approved. + rpc ReleaseCrossChainIndexingProposal(ReleaseCrossChainIndexingProposalInput) returns (google.protobuf.Empty) { + } + + // Request side chain creation. + rpc RequestSideChainCreation(SideChainCreationRequest) returns (google.protobuf.Empty){ + } + + // Release the side chain creation request if already approved and it will call the method CreateSideChain. + rpc ReleaseSideChainCreation(ReleaseSideChainCreationInput) returns (google.protobuf.Empty){ + } + + // Create the side chain and returns the newly created side chain ID. + // Only SideChainLifetimeController is permitted to invoke this method. + rpc CreateSideChain (CreateSideChainInput) returns (google.protobuf.Int32Value) { + } + + // Recharge for the specified side chain. + rpc Recharge (RechargeInput) returns (google.protobuf.Empty) { + } + + // Dispose a side chain according to side chain id. + // Only SideChainLifetimeController is permitted to invoke this method. + rpc DisposeSideChain (google.protobuf.Int32Value) returns (google.protobuf.Int32Value) { + } + + // Adjust side chain indexing fee. Only IndexingFeeController is permitted to invoke this method. + rpc AdjustIndexingFeePrice(AdjustIndexingFeeInput)returns(google.protobuf.Empty){ + } + + // Verify cross chain transaction. + rpc VerifyTransaction (VerifyTransactionInput) returns (google.protobuf.BoolValue) { + option (aelf.is_view) = true; + } + + // Gets all the side chain id and height of the current chain. + rpc GetSideChainIdAndHeight (google.protobuf.Empty) returns (ChainIdAndHeightDict) { + option (aelf.is_view) = true; + } + + // Get indexing information of side chains. + rpc GetSideChainIndexingInformationList (google.protobuf.Empty) returns (SideChainIndexingInformationList) { + option (aelf.is_view) = true; + } + + // Get id and recorded height of all chains. + rpc GetAllChainsIdAndHeight (google.protobuf.Empty) returns (ChainIdAndHeightDict) { + option (aelf.is_view) = true; + } + + // Get block data of indexed side chain according to height. + rpc GetIndexedSideChainBlockDataByHeight (google.protobuf.Int64Value) returns (IndexedSideChainBlockData) { + option (aelf.is_view) = true; + } + + // Get merkle path bound up with side chain according to height. + rpc GetBoundParentChainHeightAndMerklePathByHeight (google.protobuf.Int64Value) returns (CrossChainMerkleProofContext) { + option (aelf.is_view) = true; + } + + // Get initialization data for specified side chain. + rpc GetChainInitializationData (google.protobuf.Int32Value) returns (ChainInitializationData) { + option (aelf.is_view) = true; + } +} + +message SideChainBlockData { + // The height of side chain block. + int64 height = 1; + // The hash of side chain block. + aelf.Hash block_header_hash = 2; + // The merkle tree root computing from transactions status in side chain block. + aelf.Hash transaction_status_merkle_tree_root = 3; + // The id of side chain. + int32 chain_id = 4; +} + +message RechargeInput { + // The chain id to recharge. + int32 chain_id = 1; + // The amount to recharge. + int64 amount = 2; +} + +message ParentChainBlockData { + // The height of parent chain. + int64 height = 1; + // The merkle tree root computing from side chain roots. + CrossChainExtraData cross_chain_extra_data = 2; + // The parent chain id. + int32 chain_id = 3; + // The merkle tree root computing from transactions status in parent chain block. + aelf.Hash transaction_status_merkle_tree_root = 4; + // Indexed block height from side chain and merkle path for this side chain block + map indexed_merkle_path = 5; + // Extra data map. + map extra_data = 6; +} + +message CrossChainExtraData { + // Merkle tree root of side chain block transaction status root. + aelf.Hash transaction_status_merkle_tree_root = 1; +} + +message ChainIdAndHeightDict { + // A collection of chain ids and heights, where the key is the chain id and the value is the height. + map id_height_dict = 1; +} + +message SideChainIndexingInformationList { + // A list contains indexing information of side chains. + repeated SideChainIndexingInformation indexing_information_list = 1; +} + +message SideChainIndexingInformation { + // The side chain id. + int32 chain_id = 1; + // The indexed height. + int64 indexed_height = 2; +} + +message CrossChainBlockData { + // The side chain block data list to index. + repeated SideChainBlockData side_chain_block_data_list = 1; + // The parent chain block data list to index. + repeated ParentChainBlockData parent_chain_block_data_list = 2; +} + +message CrossChainMerkleProofContext { + // The height of parent chain bound up with side chain. + int64 bound_parent_chain_height = 1; + // The merkle path generated from parent chain. + aelf.MerklePath merkle_path_from_parent_chain = 2; +} + +message ChainInitializationData { + // The id of side chain. + int32 chain_id = 1; + // The side chain creator. + aelf.Address creator = 2; + // The timestamp for side chain creation. + google.protobuf.Timestamp creation_timestamp = 3; + // The height of side chain creation on parent chain. + int64 creation_height_on_parent_chain = 4; + // Creator privilege boolean flag: True if chain creator privilege preserved, otherwise false. + bool chain_creator_privilege_preserved = 5; + // Parent chain token contract address. + aelf.Address parent_chain_token_contract_address = 6; + // Initial consensus information. + ChainInitializationConsensusInfo chain_initialization_consensus_info = 7; + // The native token info. + bytes native_token_info_data = 8; + // The resource token information. + ResourceTokenInfo resource_token_info = 9; + // The chain primary token information. + ChainPrimaryTokenInfo chain_primary_token_info = 10; +} + +message ResourceTokenInfo{ + // The resource token information. + bytes resource_token_list_data = 1; + // The initial resource token amount. + map initial_resource_amount = 2; +} + +message ChainPrimaryTokenInfo{ + // The side chain primary token data. + bytes chain_primary_token_data = 1; + // The side chain primary token initial issue list. + repeated SideChainTokenInitialIssue side_chain_token_initial_issue_list = 2; +} + +message ChainInitializationConsensusInfo{ + // Initial consensus data. + bytes initial_consensus_data = 1; +} + +message SideChainCreationRequest { + // The cross chain indexing price. + int64 indexing_price = 1; + // Initial locked balance for a new side chain. + int64 locked_token_amount = 2; + // Creator privilege boolean flag: True if chain creator privilege preserved, otherwise false. + bool is_privilege_preserved = 3; + // Side chain token information. + SideChainTokenCreationRequest side_chain_token_creation_request = 4; + // A list of accounts and amounts that will be issued when the chain starts. + repeated SideChainTokenInitialIssue side_chain_token_initial_issue_list = 5; + // The initial rent resources. + map initial_resource_amount = 6; +} + +message SideChainTokenCreationRequest{ + // Token symbol of the side chain to be created + string side_chain_token_symbol = 1; + // Token name of the side chain to be created + string side_chain_token_name = 2; + // Token total supply of the side chain to be created + int64 side_chain_token_total_supply = 3; + // Token decimals of the side chain to be created + int32 side_chain_token_decimals = 4; +} + +message SideChainTokenInitialIssue{ + // The account that will be issued. + aelf.Address address = 1; + // The amount that will be issued. + int64 amount = 2; +} + +message IndexedParentChainBlockData { + // The height of the local chain when indexing the parent chain. + int64 local_chain_height = 1; + // Parent chain block data. + repeated acs7.ParentChainBlockData parent_chain_block_data_list = 2; +} + +message IndexedSideChainBlockData{ + // Side chain block data. + repeated acs7.SideChainBlockData side_chain_block_data_list = 1; +} + +message ReleaseCrossChainIndexingProposalInput{ + // List of chain ids to release. + repeated int32 chain_id_list = 1; +} + +message CreateSideChainInput{ + // The request information of the side chain creation. + SideChainCreationRequest side_chain_creation_request = 1; + // The proposer of the side chain creation. + aelf.Address proposer = 2; +} + +message ReleaseSideChainCreationInput { + // The proposal id of side chain creation. + aelf.Hash proposal_id = 1; +} + +message AdjustIndexingFeeInput{ + // The side chain id to adjust. + int32 side_chain_id = 1; + // The new price of indexing fee. + int64 indexing_fee = 2; +} + +message SideChainBlockDataIndexed{ + option (aelf.is_event) = true; +} + +message CrossChainIndexingDataProposedEvent{ + option (aelf.is_event) = true; + // Proposed cross chain data to be indexed. + acs7.CrossChainBlockData proposed_cross_chain_data = 1; + // The proposal id. + aelf.Hash proposal_id = 2; +} + +message VerifyTransactionInput { + // The cross chain transaction id to verify. + aelf.Hash transaction_id = 1; + // The merkle path of the transaction. + aelf.MerklePath path = 2; + // The height of parent chain that indexing this transaction. + int64 parent_chain_height = 3; + // The chain if to verify. + int32 verified_chain_id = 4; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs8.proto b/src/AElf.Client.Protobuf/Protobuf/acs8.proto new file mode 100644 index 0000000..a711fdf --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs8.proto @@ -0,0 +1,35 @@ +/** + * AElf Standards ACS8(Transaction Resource Token Fee Standard) + * + * ACS8 has some similarities to ACS1, both of them are charge transaction fee standard. + * The difference is that ACS1 charges the user a transaction fee, ACS8 charges the called contract, + * and the transaction fee charged by ACS8 is the specified four tokens: WRITE, READ, STORAGE, TRAFFIC. + * In another word, if a contract declares that it inherits from ACS8, each transaction in this contract will + * charge four kinds of resource token. + */ +syntax = "proto3"; + +package acs8; + +import public "aelf/options.proto"; +import public "google/protobuf/empty.proto"; + +option (aelf.identity) = "acs8"; +option csharp_namespace = "AElf.Standards.ACS8"; + +service ResourceConsumptionContract { + // Buy one of the four resource coins, which consumes the ELF balance in the contract account + // (you can recharge it yourself, or you can collect the user’s ELF tokens as a profit to be self-sufficient). + rpc BuyResourceToken (BuyResourceTokenInput) returns (google.protobuf.Empty) { + } +} + +message BuyResourceTokenInput { + // The symbol token you want to buy. + string symbol = 1; + // The amount you want to buy. + int64 amount = 2; + // Limit of cost. If the token required for buy exceeds this value, the buy will be abandoned. + // And 0 is no limit. + int64 pay_limit = 3; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/acs9.proto b/src/AElf.Client.Protobuf/Protobuf/acs9.proto new file mode 100644 index 0000000..dedf8e2 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/acs9.proto @@ -0,0 +1,52 @@ +/** + * AElf Standards ACS9 (Contract Profit Dividend Standard) + * + * Used for developers implement a profit divided mechanism on the AElf side chain. + */ +syntax = "proto3"; + +package acs9; + +import public "aelf/options.proto"; +import public "google/protobuf/empty.proto"; + +option (aelf.identity) = "acs9"; +option csharp_namespace = "AElf.Standards.ACS9"; + +service ContractProfitsContract { + // Used for the developer to collect the profits from the contract, + // and the profits will be distributed in this method. + rpc TakeContractProfits (TakeContractProfitsInput) returns (google.protobuf.Empty) { + } + + // Query the config of profit. + rpc GetProfitConfig (google.protobuf.Empty) returns (ProfitConfig) { + option (aelf.is_view) = true; + } + + // Query the profits of the contract so far. + rpc GetProfitsAmount (google.protobuf.Empty) returns (ProfitsMap) { + option (aelf.is_view) = true; + } +} + +message TakeContractProfitsInput { + // The token symbol to take. + string symbol = 1; + // The amount to take. + int64 amount = 2; +} + +message ProfitConfig { + // The portion of the profit that will be donated to the dividend pool each time the developer receives the profit. + int32 donation_parts_per_hundred = 1; + // The profit token symbol list. + repeated string profits_token_symbol_list = 2; + // The token symbol that the user can lock them to claim the profit. + string staking_token_symbol = 3; +} + +message ProfitsMap { + // The profits, token symbol -> amount. + map value = 1; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/aedpos_contract.proto b/src/AElf.Client.Protobuf/Protobuf/aedpos_contract.proto new file mode 100644 index 0000000..05546ab --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/aedpos_contract.proto @@ -0,0 +1,440 @@ +/** + * AEDPoS contract. + */ +syntax = "proto3"; + +package AEDPoS; + +import "aelf/options.proto"; +import "aelf/core.proto"; +import "authority_info.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; + +option csharp_namespace = "AElf.Contracts.Consensus.AEDPoS"; + +service AEDPoSContract { + + option (aelf.csharp_state) = "AElf.Contracts.Consensus.AEDPoS.AEDPoSContractState"; + + // Initialize the consensus contract. + rpc InitialAElfConsensusContract (InitialAElfConsensusContractInput) returns (google.protobuf.Empty) { + } + + // Initializes the consensus information in the first round. + rpc FirstRound (Round) returns (google.protobuf.Empty) { + } + + // Update consensus information. + rpc UpdateValue (UpdateValueInput) returns (google.protobuf.Empty) { + } + + // Update consensus information, create a new round. + rpc NextRound (Round) returns (google.protobuf.Empty) { + } + + // Update consensus information, create a new term. + rpc NextTerm (Round) returns (google.protobuf.Empty) { + } + + // Update consensus tiny block information. + rpc UpdateTinyBlockInformation (TinyBlockInput) returns (google.protobuf.Empty) { + } + + // Set the maximum count of miners, by default, is unlimited. + // If you want to control the count of miners, you need to set it through parliament. + rpc SetMaximumMinersCount (google.protobuf.Int32Value) returns (google.protobuf.Empty) { + } + + // The authority information for SetMaximumMinersCount, by default, is governed by parliament. + rpc ChangeMaximumMinersCountController (AuthorityInfo) returns (google.protobuf.Empty) { + } + + // Election Contract can notify AEDPoS Contract to aware candidate replacement happened. + rpc RecordCandidateReplacement (RecordCandidateReplacementInput) returns (google.protobuf.Empty) { + } + + // Get the list of current miners. + rpc GetCurrentMinerList (google.protobuf.Empty) returns (MinerList) { + option (aelf.is_view) = true; + } + + // Get the list of current miners (hexadecimal format). + rpc GetCurrentMinerPubkeyList (google.protobuf.Empty) returns (PubkeyList) { + option (aelf.is_view) = true; + } + + // Get the list of current miners and current round number. + rpc GetCurrentMinerListWithRoundNumber (google.protobuf.Empty) returns (MinerListWithRoundNumber) { + option (aelf.is_view) = true; + } + + // Get information of the round according to round number. + rpc GetRoundInformation (google.protobuf.Int64Value) returns (Round) { + option (aelf.is_view) = true; + } + + // Get the current round number. + rpc GetCurrentRoundNumber (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the current round information. + rpc GetCurrentRoundInformation (google.protobuf.Empty) returns (Round) { + option (aelf.is_view) = true; + } + + // Get the previous round information. + rpc GetPreviousRoundInformation (google.protobuf.Empty) returns (Round) { + option (aelf.is_view) = true; + } + + // Get the current term number. + rpc GetCurrentTermNumber (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the welfare reward the current term. + rpc GetCurrentTermMiningReward (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the list of miners according to term number. + rpc GetMinerList (GetMinerListInput) returns (MinerList) { + option (aelf.is_view) = true; + } + + // Get the list of miner in previous term. + rpc GetPreviousMinerList (google.protobuf.Empty) returns (MinerList) { + option (aelf.is_view) = true; + } + + // Get the amount of mined blocks in previous term. + rpc GetMinedBlocksOfPreviousTerm (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the miner that produces the next block. + rpc GetNextMinerPubkey (google.protobuf.Empty) returns (google.protobuf.StringValue) { + option (aelf.is_view) = true; + } + + // Check to see if the account address is on the miner list for the current round. + rpc IsCurrentMiner (aelf.Address) returns (google.protobuf.BoolValue) { + option (aelf.is_view) = true; + } + + // Query the left time before the next election takes effects (seconds). + rpc GetNextElectCountDown (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get term information according term number. + rpc GetPreviousTermInformation (google.protobuf.Int64Value) returns (Round) { + option (aelf.is_view) = true; + } + + // Get random hash (Keep this for compatibility). + rpc GetRandomHash (google.protobuf.Int64Value) returns (aelf.Hash) { + option (aelf.is_view) = true; + } + + // Get the maximum of tiny blocks produced by a miner each round. + rpc GetMaximumBlocksCount (google.protobuf.Empty) returns (google.protobuf.Int32Value) { + option (aelf.is_view) = true; + } + + // Get the maximum count of miners. + rpc GetMaximumMinersCount (google.protobuf.Empty) returns (google.protobuf.Int32Value) { + option (aelf.is_view) = true; + } + + // Get the authority information for SetMaximumMinersCount. + rpc GetMaximumMinersCountController (google.protobuf.Empty) returns (AuthorityInfo) { + option (aelf.is_view) = true; + } + + // Gets the list of miners in the main chain. + rpc GetMainChainCurrentMinerList (google.protobuf.Empty) returns (MinerList) { + option (aelf.is_view) = true; + } + + // Get the list of miners in the previous term. + rpc GetPreviousTermMinerPubkeyList (google.protobuf.Empty) returns (PubkeyList) { + option (aelf.is_view) = true; + } + + // Query the current mining reward for each block. + rpc GetCurrentMiningRewardPerBlock (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } +} + +message InitialAElfConsensusContractInput { + // Whether not to change the term. + bool is_term_stay_one = 1; + // Is a side chain. + bool is_side_chain = 2; + // The number of seconds per term. + int64 period_seconds = 3; + // The interval second that increases the number of miners. + int64 miner_increase_interval = 4; +} + +message UpdateValueInput { + // Calculated from current in value. + aelf.Hash out_value = 1; + // Calculated from current in value and signatures of previous round. + aelf.Hash signature = 2; + // To ensure the values to update will be apply to correct round by comparing round id. + int64 round_id = 3; + // Publish previous in value for validation previous signature and previous out value. + aelf.Hash previous_in_value = 4; + // The actual mining time, miners must fill actual mining time when they do the mining. + google.protobuf.Timestamp actual_mining_time = 5; + // The supposed order of mining for the next round. + int32 supposed_order_of_next_round = 6; + // The tuning order of mining for the next round, miner public key -> order. + map tune_order_information = 7; + // The encrypted pieces of InValue. + map encrypted_pieces = 8; + // The decrypted pieces of InValue. + map decrypted_pieces = 9; + // The amount of produced blocks. + int64 produced_blocks = 10; + // The InValue in the previous round, miner public key -> InValue. + map miners_previous_in_values = 11; + // The irreversible block height that miner recorded. + int64 implied_irreversible_block_height = 12; +} + +message MinerList { + // The miners public key list. + repeated bytes pubkeys = 1; +} + +message PubkeyList { + // The miners public key list. + repeated string pubkeys = 1; +} + +message TermNumberLookUp { + // Term number -> Round number. + map map = 1; +} + +message Candidates { + // The candidate public keys. + repeated bytes pubkeys = 1; +} + +message Round { + // The round number. + int64 round_number = 1; + // Current miner information, miner public key -> miner information. + map real_time_miners_information = 2; + // The round number on the main chain + int64 main_chain_miners_round_number = 3; + // The time from chain start to current round (seconds). + int64 blockchain_age = 4; + // The miner public key that produced the extra block in the previous round. + string extra_block_producer_of_previous_round = 5; + // The current term number. + int64 term_number = 6; + // The height of the confirmed irreversible block. + int64 confirmed_irreversible_block_height = 7; + // The round number of the confirmed irreversible block. + int64 confirmed_irreversible_block_round_number = 8; + // Is miner list different from the the miner list in the previous round. + bool is_miner_list_just_changed = 9; + // The round id, calculated by summing block producers’ expecting time (second). + int64 round_id_for_validation = 10; +} + +message MinerInRound { + // The order of the miner producing block. + int32 order = 1; + // Is extra block producer in the current round. + bool is_extra_block_producer = 2; + // Generated by secret sharing and used for validation between miner. + aelf.Hash in_value = 3; + // Calculated from current in value. + aelf.Hash out_value = 4; + // Calculated from current in value and signatures of previous round. + aelf.Hash signature = 5; + // The expected mining time. + google.protobuf.Timestamp expected_mining_time = 6; + // The amount of produced blocks. + int64 produced_blocks = 7; + // The amount of missed time slots. + int64 missed_time_slots = 8; + // The public key of this miner. + string pubkey = 9; + // The InValue of the previous round. + aelf.Hash previous_in_value = 10; + // The supposed order of mining for the next round. + int32 supposed_order_of_next_round = 11; + // The final order of mining for the next round. + int32 final_order_of_next_round = 12; + // The actual mining time, miners must fill actual mining time when they do the mining. + repeated google.protobuf.Timestamp actual_mining_times = 13; + // The encrypted pieces of InValue. + map encrypted_pieces = 14; + // The decrypted pieces of InValue. + map decrypted_pieces = 15; + // The amount of produced tiny blocks. + int64 produced_tiny_blocks = 16; + // The irreversible block height that current miner recorded. + int64 implied_irreversible_block_height = 17; +} + +message AElfConsensusHeaderInformation { + // The sender public key. + bytes sender_pubkey = 1; + // The round information. + Round round = 2; + // The behaviour of consensus. + AElfConsensusBehaviour behaviour = 3; +} + +message AElfConsensusHint { + // The behaviour of consensus. + AElfConsensusBehaviour behaviour = 1; + // The round id. + int64 round_id = 2; + // The previous round id. + int64 previous_round_id = 3; +} + +enum AElfConsensusBehaviour { + UPDATE_VALUE = 0; + NEXT_ROUND = 1; + NEXT_TERM = 2; + NOTHING = 3; + TINY_BLOCK = 4; +} + +message AElfConsensusTriggerInformation { + // The miner public key. + bytes pubkey = 1; + // The InValue for current round. + aelf.Hash in_value = 2; + // The InValue for previous round. + aelf.Hash previous_in_value = 3; + // The behaviour of consensus. + AElfConsensusBehaviour behaviour = 4; + // The encrypted pieces of InValue. + map encrypted_pieces = 5; + // The decrypted pieces of InValue. + map decrypted_pieces = 6; + // The revealed InValues. + map revealed_in_values = 7; +} + +message TermInfo { + int64 term_number = 1; + int64 round_number = 2; +} + +message MinerListWithRoundNumber { + // The list of miners. + MinerList miner_list = 1; + // The round number. + int64 round_number = 2; +} + +message TinyBlockInput { + // The round id. + int64 round_id = 1; + // The actual mining time. + google.protobuf.Timestamp actual_mining_time = 2; + // Count of blocks currently produced + int64 produced_blocks = 3; +} + +message VoteMinersCountInput { + int32 miners_count = 1; + int64 amount = 2; +} + +message ConsensusInformation { + bytes value = 1; +} + +message GetMinerListInput { + // The term number. + int64 term_number = 1; +} + +message RandomNumberRequestInformation { + int64 target_round_number = 1;// The random hash is likely generated during this round. + int64 order = 2; + int64 expected_block_height = 3; +} + +message HashList { + repeated aelf.Hash values = 1; +} + +message LatestPubkeyToTinyBlocksCount { + // The miner public key. + string pubkey = 1; + // The count of blocks the miner produced. + int64 blocks_count = 2; +} + +message IrreversibleBlockFound { + option (aelf.is_event) = true; + // The irreversible block height found. + int64 irreversible_block_height = 1 [(aelf.is_indexed) = true]; +} + +message IrreversibleBlockHeightUnacceptable { + option (aelf.is_event) = true; + // Distance to the height of the last irreversible block. + int64 distance_to_irreversible_block_height = 1; +} + +message MiningInformationUpdated { + option (aelf.is_event) = true; + // The miner public key. + string pubkey = 1 [(aelf.is_indexed) = true]; + // The current block time. + google.protobuf.Timestamp mining_time = 2 [(aelf.is_indexed) = true]; + // The behaviour of consensus. + string behaviour = 3 [(aelf.is_indexed) = true]; + // The current block height. + int64 block_height = 4 [(aelf.is_indexed) = true]; + // The previous block hash. + aelf.Hash previous_block_hash = 5 [(aelf.is_indexed) = true]; +} + +message SecretSharingInformation { + option (aelf.is_event) = true; + // The previous round information. + Round previous_round = 1 [(aelf.is_indexed) = true]; + // The current round id. + int64 current_round_id = 2; + // The previous round id. + int64 previous_round_id = 3; +} + +message MiningRewardGenerated { + option (aelf.is_event) = true; + // The number of term the mining reward is generated. + int64 term_number = 1 [(aelf.is_indexed) = true]; + // The amount of mining reward. + int64 amount = 2; +} + +message MinerReplaced { + option (aelf.is_event) = true; + // The new miner public key. + string new_miner_pubkey = 1; +} + +message RecordCandidateReplacementInput { + string old_pubkey = 1; + string new_pubkey = 2; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/aelf/core.proto b/src/AElf.Client.Protobuf/Protobuf/aelf/core.proto new file mode 100644 index 0000000..e410996 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/aelf/core.proto @@ -0,0 +1,147 @@ +syntax = "proto3"; + +package aelf; + +option csharp_namespace = "AElf.Types"; + +message Transaction { + // The address of the sender of the transaction. + Address from = 1; + // The address of the contract when calling a contract. + Address to = 2; + // The height of the referenced block hash. + int64 ref_block_number = 3; + // The first four bytes of the referenced block hash. + bytes ref_block_prefix = 4; + // The name of a method in the smart contract at the To address. + string method_name = 5; + // The parameters to pass to the smart contract method. + bytes params = 6; + // When signing a transaction it’s actually a subset of the fields: from/to and the target method as well as + // the parameter that were given. It also contains the reference block number and prefix. + bytes signature = 10000; +} + +message StatePath { + // The partial path of the state path. + repeated string parts = 1; +} + +message ScopedStatePath { + // The scope address, which will be the contract address. + Address address = 1; + // The path of contract state. + StatePath path = 2; +} + +enum TransactionResultStatus { + // The execution result of the transaction does not exist. + NOT_EXISTED = 0; + // The transaction is in the transaction pool waiting to be packaged. + PENDING = 1; + // Transaction execution failed. + FAILED = 2; + // The transaction was successfully executed and successfully packaged into a block. + MINED = 3; + // When executed in parallel, there are conflicts with other transactions. + CONFLICT = 4; + // The transaction is waiting for validation. + PENDING_VALIDATION = 5; + // Transaction validation failed. + NODE_VALIDATION_FAILED = 6; +} + +message TransactionResult { + // The transaction id. + Hash transaction_id = 1; + // The transaction result status. + TransactionResultStatus status = 2; + // The log events. + repeated LogEvent logs = 3; + // Bloom filter for transaction logs. A transaction log event can be defined in the contract and stored + // in the bloom filter after the transaction is executed. Through this filter, we can quickly search for + // and determine whether a log exists in the transaction result. + bytes bloom = 4; + // The return value of the transaction execution. + bytes return_value = 5; + // The height of the block hat packages the transaction. + int64 block_number = 6; + // The hash of the block hat packages the transaction. + Hash block_hash = 7; + // Failed execution error message. + string error = 10; +} + +message LogEvent { + // The contract address. + Address address = 1; + // The name of the log event. + string name = 2; + // The indexed data, used to calculate bloom. + repeated bytes indexed = 3; + // The non indexed data. + bytes non_indexed = 4; +} + +message SmartContractRegistration { + // The category of contract code(0: C#). + sint32 category = 1; + // The byte array of the contract code. + bytes code = 2; + // The hash of the contract code. + Hash code_hash = 3; + // Whether it is a system contract. + bool is_system_contract = 4; + // The version of the current contract. + int32 version = 5; +} + +message TransactionExecutingStateSet { + // The changed states. + map writes = 1; + // The read states. + map reads = 2; + // The deleted states. + map deletes = 3; +} + +message Address +{ + bytes value = 1; +} + +message Hash +{ + bytes value = 1; +} + +message SInt32Value +{ + sint32 value = 1; +} + +message SInt64Value +{ + sint64 value = 1; +} + +message MerklePath { + // The merkle path nodes. + repeated MerklePathNode merkle_path_nodes = 1; +} + +message MerklePathNode{ + // The node hash. + Hash hash = 1; + // Whether it is a left child node. + bool is_left_child_node = 2; +} + +message BinaryMerkleTree { + // The leaf nodes. + repeated Hash nodes = 1; + // The root node hash. + Hash root = 2; + // The count of leaf node. + int32 leaf_count = 3; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/aelf/options.proto b/src/AElf.Client.Protobuf/Protobuf/aelf/options.proto new file mode 100644 index 0000000..34058ba --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/aelf/options.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package aelf; + +import "google/protobuf/descriptor.proto"; + +option csharp_namespace = "AElf"; + +// All aelf custom options field numbers are like 50yxxx +// where y stands for the custom options type: +// 0 - FileOptions +// 1 - MessageOptions +// 2 - FieldOptions +// 3 - EnumOptions +// 4 - EnumValueOptions +// 5 - ServiceOptions +// 6 - MethodOptions + +extend google.protobuf.FileOptions { + string identity = 500001; +} + +extend google.protobuf.ServiceOptions { + repeated string base = 505001; + string csharp_state = 505030; +} + +extend google.protobuf.MethodOptions { + bool is_view = 506001; +} + +extend google.protobuf.MessageOptions { + bool is_event = 50100; +} + +extend google.protobuf.FieldOptions { + bool is_indexed = 502001; +} diff --git a/src/AElf.Client.Protobuf/Protobuf/association_contract.proto b/src/AElf.Client.Protobuf/Protobuf/association_contract.proto new file mode 100644 index 0000000..2efb821 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/association_contract.proto @@ -0,0 +1,144 @@ +/** + * Association contract. + */ +syntax = "proto3"; + +package Association; + +import "acs3.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +option csharp_namespace = "AElf.Contracts.Association"; + +service AssociationContract { + + option (aelf.csharp_state) = "AElf.Contracts.Association.AssociationState"; + + // Create an organization and return its address. + rpc CreateOrganization (CreateOrganizationInput) returns (aelf.Address) { + } + + // Creates an organization by system contract and return its address. + rpc CreateOrganizationBySystemContract(CreateOrganizationBySystemContractInput) returns (aelf.Address){ + } + + // Add organization members. + rpc AddMember(aelf.Address) returns (google.protobuf.Empty){ + } + + // Remove organization members. + rpc RemoveMember(aelf.Address) returns (google.protobuf.Empty){ + } + + // Replace organization member with a new member. + rpc ChangeMember(ChangeMemberInput) returns (google.protobuf.Empty){ + } + + // Get the organization according to the organization address. + rpc GetOrganization (aelf.Address) returns (Organization) { + option (aelf.is_view) = true; + } + + // Calculate the input and return the organization address. + rpc CalculateOrganizationAddress(CreateOrganizationInput) returns (aelf.Address){ + option (aelf.is_view) = true; + } +} + +message CreateOrganizationInput{ + // Initial organization members. + OrganizationMemberList organization_member_list = 1; + // The threshold for releasing the proposal. + acs3.ProposalReleaseThreshold proposal_release_threshold = 2; + // The proposer whitelist. + acs3.ProposerWhiteList proposer_white_list = 3; + // The creation token is for organization address generation. + aelf.Hash creation_token = 4; +} + +message Organization{ + // The organization members. + OrganizationMemberList organization_member_list = 1; + // The threshold for releasing the proposal. + acs3.ProposalReleaseThreshold proposal_release_threshold = 2; + // The proposer whitelist. + acs3.ProposerWhiteList proposer_white_list = 3; + // The address of organization. + aelf.Address organization_address = 4; + // The organizations id. + aelf.Hash organization_hash = 5; + // The creation token is for organization address generation. + aelf.Hash creation_token = 6; +} + +message ProposalInfo { + // The proposal ID. + aelf.Hash proposal_id = 1; + // The method that this proposal will call when being released. + string contract_method_name = 2; + // The address of the target contract. + aelf.Address to_address = 3; + // The parameters of the release transaction. + bytes params = 4; + // The date at which this proposal will expire. + google.protobuf.Timestamp expired_time = 5; + // The address of the proposer of this proposal. + aelf.Address proposer = 6; + // The address of this proposals organization. + aelf.Address organization_address = 7; + // Address list of approved. + repeated aelf.Address approvals = 8; + // Address list of rejected. + repeated aelf.Address rejections = 9; + // Address list of abstained. + repeated aelf.Address abstentions = 10; + // Url is used for proposal describing. + string proposal_description_url = 11; +} + +message OrganizationMemberList { + // The address of organization members. + repeated aelf.Address organization_members = 1; +} + +message ChangeMemberInput{ + // The old member address. + aelf.Address old_member = 1; + // The new member address. + aelf.Address new_member = 2; +} + +message CreateOrganizationBySystemContractInput { + // The parameters of creating organization. + CreateOrganizationInput organization_creation_input = 1; + // The organization address callback method which replies the organization address to caller contract. + string organization_address_feedback_method = 2; +} + +message MemberAdded{ + option (aelf.is_event) = true; + // The added member address. + aelf.Address member = 1; + // The organization address. + aelf.Address organization_address = 2 [(aelf.is_indexed) = true]; +} + +message MemberRemoved{ + option (aelf.is_event) = true; + // The removed member address. + aelf.Address member = 1; + // The organization address. + aelf.Address organization_address = 2 [(aelf.is_indexed) = true]; +} + +message MemberChanged{ + option (aelf.is_event) = true; + // The old member address. + aelf.Address old_member = 1; + // The new member address. + aelf.Address new_member = 2; + // The organization address. + aelf.Address organization_address = 3 [(aelf.is_indexed) = true]; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/authority_info.proto b/src/AElf.Client.Protobuf/Protobuf/authority_info.proto new file mode 100644 index 0000000..65302e8 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/authority_info.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +import "aelf/core.proto"; + +message AuthorityInfo { + // The contract address of the controller. + aelf.Address contract_address = 1; + // The address of the owner of the contract. + aelf.Address owner_address = 2; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/basic_contract_zero.proto b/src/AElf.Client.Protobuf/Protobuf/basic_contract_zero.proto new file mode 100644 index 0000000..5c14ec0 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/basic_contract_zero.proto @@ -0,0 +1,71 @@ +/** + * Genesis contract. + */ +syntax = "proto3"; + +package Zero; + +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "aelf/core.proto"; +import "google/protobuf/timestamp.proto"; +import "authority_info.proto"; + +option csharp_namespace = "AElf.Contracts.Genesis"; + +service BasicContractZero { + option (aelf.csharp_state) = "AElf.Contracts.Genesis.BasicContractZeroState"; + + // Initialize the genesis contract. + rpc Initialize (InitializeInput) returns (google.protobuf.Empty) { + } + + // Set initial controller address for CodeCheckController and ContractDeploymentController. + rpc SetInitialControllerAddress (aelf.Address) returns (google.protobuf.Empty) { + } + + // Modify the contract deployment controller authority. + // Note: Only old controller has permission to do this. + rpc ChangeContractDeploymentController (AuthorityInfo) returns (google.protobuf.Empty) { + } + + // Modify the contract code check controller authority. + // Note: Only old controller has permission to do this. + rpc ChangeCodeCheckController (AuthorityInfo) returns (google.protobuf.Empty) { + } + + // Query the ContractDeploymentController authority info. + rpc GetContractDeploymentController (google.protobuf.Empty) returns (AuthorityInfo) { + option (aelf.is_view) = true; + } + + // Query the CodeCheckController authority info. + rpc GetCodeCheckController(google.protobuf.Empty) returns (AuthorityInfo){ + option (aelf.is_view) = true; + } +} + +message InitializeInput{ + // Whether contract deployment/update requires authority. + bool contract_deployment_authority_required = 1; +} + +message ContractProposingInput{ + // The address of proposer for contract deployment/update. + aelf.Address proposer = 1; + // The status of proposal. + ContractProposingInputStatus status = 2; + // The expiration time of proposal. + google.protobuf.Timestamp expired_time = 3; +} + +enum ContractProposingInputStatus { + // Proposal is proposed. + PROPOSED = 0; + // Proposal is approved by parliament. + APPROVED = 1; + // Code check is proposed. + CODE_CHECK_PROPOSED = 2; + // Passed code checks. + CODE_CHECKED = 3; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/configuration_contract.proto b/src/AElf.Client.Protobuf/Protobuf/configuration_contract.proto new file mode 100644 index 0000000..041e726 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/configuration_contract.proto @@ -0,0 +1,52 @@ +/** + * Configuration contract. + */ +syntax = "proto3"; + +package Configuration; + +import "aelf/core.proto"; +import "google/protobuf/wrappers.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "authority_info.proto"; + +option csharp_namespace = "AElf.Contracts.Configuration"; + +service Configuration { + option (aelf.csharp_state) = "AElf.Contracts.Configuration.ConfigurationState"; + + // Add or update configuration. + rpc SetConfiguration (SetConfigurationInput) returns (google.protobuf.Empty) { + } + + // Change the method fee controller, the default is Parliament. + rpc ChangeConfigurationController (AuthorityInfo) returns (google.protobuf.Empty) { + } + + // Query the configuration by configuration’s key. + rpc GetConfiguration (google.protobuf.StringValue) returns (google.protobuf.BytesValue) { + option (aelf.is_view) = true; + } + + // Query the controller information + rpc GetConfigurationController (google.protobuf.Empty) returns (AuthorityInfo) { + option (aelf.is_view) = true; + } + +} + +message SetConfigurationInput { + // The configuration’s key. + string key = 1; + // The configuration’s value(binary data). + bytes value = 2; +} + +message ConfigurationSet { + option (aelf.is_event) = true; + // The configuration’s key. + string key = 1; + // The configuration’s value(binary data). + bytes value = 2; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/cross_chain_contract.proto b/src/AElf.Client.Protobuf/Protobuf/cross_chain_contract.proto new file mode 100644 index 0000000..5441a66 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/cross_chain_contract.proto @@ -0,0 +1,266 @@ +/** + * Cross-Chain contract. + */ +syntax = "proto3"; + +package CrossChain; + +import "acs7.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; +import "authority_info.proto"; + +option csharp_namespace = "AElf.Contracts.CrossChain"; + +service CrossChainContract { + + option (aelf.csharp_state) = "AElf.Contracts.CrossChain.CrossChainContractState"; + + // Propose once cross chain indexing. + rpc Initialize (InitializeInput) returns (google.protobuf.Empty) { + } + + // Set the initial SideChainLifetimeController address which should be parliament organization by default. + rpc SetInitialSideChainLifetimeControllerAddress(aelf.Address) returns (google.protobuf.Empty){ + } + + // Set the initial CrossChainIndexingController address which should be parliament organization by default. + rpc SetInitialIndexingControllerAddress(aelf.Address) returns (google.protobuf.Empty){ + } + + // Change the cross chain indexing controller. + rpc ChangeCrossChainIndexingController(AuthorityInfo) returns (google.protobuf.Empty) { + } + + // Change the lifetime controller of the side chain. + rpc ChangeSideChainLifetimeController(AuthorityInfo) returns (google.protobuf.Empty) { + } + + // Change indexing fee adjustment controller for specific side chain. + rpc ChangeSideChainIndexingFeeController(ChangeSideChainIndexingFeeControllerInput) returns (google.protobuf.Empty){ + } + + // When the indexing proposal is released, clean up the pending proposal. + rpc AcceptCrossChainIndexingProposal(AcceptCrossChainIndexingProposalInput) returns (google.protobuf.Empty){ + } + + // Get the side chain creator address according to side chain id. + rpc GetSideChainCreator (google.protobuf.Int32Value) returns (aelf.Address) { + option (aelf.is_view) = true; + } + + // Get the current status of side chain according to side chain id. + rpc GetChainStatus (google.protobuf.Int32Value) returns (GetChainStatusOutput) { + option (aelf.is_view) = true; + } + + // Get the side chain height according to side chain id. + rpc GetSideChainHeight (google.protobuf.Int32Value) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the height of parent chain. + rpc GetParentChainHeight (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the chain id of parent chain. + rpc GetParentChainId (google.protobuf.Empty) returns (google.protobuf.Int32Value) { + option (aelf.is_view) = true; + } + + // Get the balance of side chain indexing according to side chain id. + rpc GetSideChainBalance (google.protobuf.Int32Value) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the fee debt of side chain indexing according to side chain id. + rpc GetSideChainIndexingFeeDebt (google.protobuf.Int32Value) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the status of the current indexing proposal. + rpc GetIndexingProposalStatus (google.protobuf.Empty) returns (GetIndexingProposalStatusOutput) { + option (aelf.is_view) = true; + } + + // Get the side chain indexing fee price according to side chain id. + rpc GetSideChainIndexingFeePrice(google.protobuf.Int32Value) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the lifetime controller of the side chain. + rpc GetSideChainLifetimeController(google.protobuf.Empty) returns (AuthorityInfo){ + option (aelf.is_view) = true; + } + + // Get the cross chain indexing controller. + rpc GetCrossChainIndexingController(google.protobuf.Empty) returns (AuthorityInfo){ + option (aelf.is_view) = true; + } + + // Get the indexing fee controller of side chain according to side chain id. + rpc GetSideChainIndexingFeeController(google.protobuf.Int32Value) returns (AuthorityInfo){ + option (aelf.is_view) = true; + } +} + +message InitializeInput { + // The id of parent chain. + int32 parent_chain_id = 1; + // The height of side chain created on parent chain. + int64 creation_height_on_parent_chain = 2; + // True if chain privilege needed, otherwise false. + bool is_privilege_preserved = 3; +} + +message SideChainCreatedEvent { + option (aelf.is_event) = true; + // The proposer who propose to create the side chain. + aelf.Address creator = 1; + // The created side chain id. + int32 chainId = 2; +} + +message Disposed { + option (aelf.is_event) = true; + // The disposed side chain id. + int32 chain_id = 1; +} + +message ProposedCrossChainIndexing{ + // The collection of chain indexing proposal, the key is chain id. + map chain_indexing_proposal_collections = 1; +} + +message ChainIndexingProposal{ + // The id of cross chain indexing proposal. + aelf.Hash proposal_id = 1; + // The proposer of cross chain indexing. + aelf.Address proposer = 2; + // The cross chain data proposed. + acs7.CrossChainBlockData proposed_cross_chain_block_data = 3; + // The status of of cross chain indexing proposal. + CrossChainIndexingProposalStatus status = 4; + // The chain id of the indexing. + int32 chain_id = 5; +} + +message GetIndexingProposalStatusOutput{ + // The collection of pending indexing proposal, the key is chain id. + map chain_indexing_proposal_status = 1; +} + +message PendingChainIndexingProposalStatus{ + // The id of cross chain indexing proposal. + aelf.Hash proposal_id = 1; + // The proposer of cross chain indexing. + aelf.Address proposer = 2; + // True if the proposal can be released, otherwise false. + bool to_be_released = 3; + // The cross chain data proposed. + acs7.CrossChainBlockData proposed_cross_chain_block_data = 4; + // The proposal expiration time. + google.protobuf.Timestamp expired_time = 5; +} + +message GetPendingCrossChainIndexingProposalOutput{ + // The proposal id of cross chain indexing. + aelf.Hash proposal_id = 1; + // The proposer of cross chain indexing proposal. + aelf.Address proposer = 2; + // True if the proposal can be released, otherwise false. + bool to_be_released = 3; + // The cross chain data proposed. + acs7.CrossChainBlockData proposed_cross_chain_block_data = 4; + // The proposal expiration time. + google.protobuf.Timestamp expired_time = 5; +} + +enum CrossChainIndexingProposalStatus{ + NON_PROPOSED = 0; + // The proposal is pending. + PENDING = 1; + // The proposal has been released. + ACCEPTED = 2; +} + +enum SideChainStatus +{ + // Currently no meaning. + FATAL = 0; + // The side chain is being indexed. + ACTIVE = 1; + // The side chain is in debt for indexing fee. + INDEXING_FEE_DEBT = 2; + // The side chain is disposed. + TERMINATED = 3; +} + +message SideChainInfo { + // The proposer who propose to create the side chain. + aelf.Address proposer = 1; + // The status of side chain. + SideChainStatus side_chain_status = 2; + // The side chain id. + int32 side_chain_id = 3; + // The time of side chain created. + google.protobuf.Timestamp creation_timestamp = 4; + // The height of side chain created on parent chain. + int64 creation_height_on_parent_chain = 5; + // The price of indexing fee. + int64 indexing_price = 6; + // True if chain privilege needed, otherwise false. + bool is_privilege_preserved = 7; + // creditor and amounts for the chain indexing fee debt + map arrears_info = 8; + // The controller of indexing fee. + AuthorityInfo indexing_fee_controller = 9; +} + +message GetChainStatusOutput{ + // The status of side chain. + SideChainStatus status = 1; +} + +message SideChainCreationRequestState{ + // The parameters of creating side chain. + acs7.SideChainCreationRequest side_chain_creation_request = 1; + // The expiration date of the proposal. + google.protobuf.Timestamp expired_time = 2; + // The proposer who proposed to create the side chain. + aelf.Address proposer = 3; +} + +message ChangeSideChainIndexingFeeControllerInput{ + // The side chain id. + int32 chain_id = 1; + // The changed controller of indexing fee. + AuthorityInfo authority_info = 2; +} + +message SideChainLifetimeControllerChanged{ + option (aelf.is_event) = true; + // The changed controller of side chain lifetime. + AuthorityInfo authority_info = 1; +} + +message CrossChainIndexingControllerChanged{ + option (aelf.is_event) = true; + // The changed controller of indexing. + AuthorityInfo authority_info = 1; +} + +message SideChainIndexingFeeControllerChanged{ + option (aelf.is_event) = true; + // The side chain id. + int32 chain_id = 1 [(aelf.is_indexed) = true]; + // The changed controller of side chain indexing fee. + AuthorityInfo authority_info = 2; +} + +message AcceptCrossChainIndexingProposalInput{ + // The chain id of accepted indexing. + int32 chain_id = 1; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/economic_contract.proto b/src/AElf.Client.Protobuf/Protobuf/economic_contract.proto new file mode 100644 index 0000000..943fe74 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/economic_contract.proto @@ -0,0 +1,62 @@ +/** + * Economic contract. + */ +syntax = "proto3"; + +package Economic; + +import "aelf/core.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; + +option csharp_namespace = "AElf.Contracts.Economic"; + +service EconomicContract { + option (aelf.csharp_state) = "AElf.Contracts.Economic.EconomicContractState"; + + // Only ZeroContract is able to issue the native token. + rpc IssueNativeToken (IssueNativeTokenInput) returns (google.protobuf.Empty) { + } + + // It will initialize other contracts related to economic activities (For instance, create the native token). + // This transaction only can be send once because after the first sending, its state will be set to initialized. + rpc InitialEconomicSystem (InitialEconomicSystemInput) returns (google.protobuf.Empty) { + } +} + +message InitialEconomicSystemInput { + // The native token symbol. + string native_token_symbol = 1; + // The native token name. + string native_token_name = 2; + // The native token total supply. + int64 native_token_total_supply = 3; + // The accuracy of the native token. + int32 native_token_decimals = 4; + // It indicates if the token is burnable. + bool is_native_token_burnable = 5; + // It determines how much native token is used to reward the miners. + int64 mining_reward_total_amount = 6; + // todo : remove unused fields + int64 transaction_size_fee_unit_price = 7; +} + +message IssueNativeTokenInput { + // The amount of token. + int64 amount = 1; + // The memo. + string memo = 2; + // The recipient of the token. + aelf.Address to = 3; +} + +message IssueResourceTokenInput { + // The symbol of resource token. + string symbol = 1; + // The amount of resource token. + int64 amount = 2; + // The memo. + string memo = 3; + // The recipient of the token. + aelf.Address to = 4; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/election_contract.proto b/src/AElf.Client.Protobuf/Protobuf/election_contract.proto new file mode 100644 index 0000000..0337e7c --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/election_contract.proto @@ -0,0 +1,522 @@ +/** + * Election contract. + */ +syntax = "proto3"; + +package Election; + +import "aelf/core.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; +import "google/protobuf/empty.proto"; +import "aelf/options.proto"; +import "authority_info.proto"; + +option csharp_namespace = "AElf.Contracts.Election"; + +service ElectionContract { + + option (aelf.csharp_state) = "AElf.Contracts.Election.ElectionContractState"; + + // Initialize the election contract. + rpc InitialElectionContract (InitialElectionContractInput) returns (google.protobuf.Empty) { + } + + // Register a new voting item through vote contract. + rpc RegisterElectionVotingEvent (google.protobuf.Empty) returns (google.protobuf.Empty) { + } + + // Take snapshot according to term number, and distribute profits. + rpc TakeSnapshot (TakeElectionSnapshotInput) returns (google.protobuf.Empty) { + } + + // To be a block producer, a user should first register to be a candidate and lock some token as a deposit. + // If the data center is not full, the user will be added in automatically and get one weight + // for sharing bonus in the future. + rpc AnnounceElection (aelf.Address) returns (google.protobuf.Empty) { + } + + // A candidate is able to quit the election provided he is not currently elected. If you quit successfully, + // the candidate will get his locked tokens back and will not receive anymore bonus. + rpc QuitElection (google.protobuf.StringValue) returns (google.protobuf.Empty) { + } + + // Used for voting for a candidate to be elected. The tokens you vote with will be locked until the end time. + // According to the number of token you voted and its lock time, you can get corresponding weight for + // sharing the bonus in the future. And return the vote id. + rpc Vote (VoteMinerInput) returns (aelf.Hash) { + } + + // Before the end time, you are able to change your vote target to other candidates. + rpc ChangeVotingOption (ChangeVotingOptionInput) returns (google.protobuf.Empty) { + } + + rpc FixWelfareProfit (FixWelfareProfitInput) returns (google.protobuf.Empty) { + } + + rpc DisableWelfareFix (google.protobuf.Empty) returns (google.protobuf.Empty) { + } + + // After the lock time, your locked tokens will be unlocked and you can withdraw them according to the vote id. + rpc Withdraw (aelf.Hash) returns (google.protobuf.Empty) { + } + + // Update candidate information by consensus contract. + rpc UpdateCandidateInformation (UpdateCandidateInformationInput) returns (google.protobuf.Empty) { + } + + // Batch update candidate information by consensus contract. + rpc UpdateMultipleCandidateInformation (UpdateMultipleCandidateInformationInput) returns (google.protobuf.Empty) { + } + + // Update the count of miner by consensus contract. + rpc UpdateMinersCount (UpdateMinersCountInput) returns (google.protobuf.Empty) { + } + + // Set the treasury profit ids. + rpc SetTreasurySchemeIds (SetTreasurySchemeIdsInput) returns (google.protobuf.Empty) { + } + + // Set the weight of vote interest. + rpc SetVoteWeightInterest (VoteWeightInterestList) returns (google.protobuf.Empty) { + } + + // Set the weight of lock time and votes in the calculation of voting weight. + rpc SetVoteWeightProportion (VoteWeightProportion) returns (google.protobuf.Empty) { + } + + // Change the controller for the weight of vote interest. + rpc ChangeVoteWeightInterestController (AuthorityInfo) returns (google.protobuf.Empty) { + } + + // Candidate admin can replace candidate pubkey with a new pubkey. + rpc ReplaceCandidatePubkey (ReplaceCandidatePubkeyInput) returns (google.protobuf.Empty) { + } + + // Set admin address of candidate (mostly supply) + rpc SetCandidateAdmin (SetCandidateAdminInput) returns (google.protobuf.Empty) { + } + + rpc RemoveEvilNode (google.protobuf.StringValue) returns (google.protobuf.Empty) { + } + + // Views + + // Get all candidates’ public keys. + rpc GetCandidates (google.protobuf.Empty) returns (PubkeyList) { + option (aelf.is_view) = true; + } + + // Get all candidates whose number of votes is greater than 0. + rpc GetVotedCandidates (google.protobuf.Empty) returns (PubkeyList) { + option (aelf.is_view) = true; + } + + // Get a candidate’s information. + rpc GetCandidateInformation (google.protobuf.StringValue) returns (CandidateInformation) { + option (aelf.is_view) = true; + } + + // Get the victories of the latest term. + rpc GetVictories (google.protobuf.Empty) returns (PubkeyList) { + option (aelf.is_view) = true; + } + + // Get the snapshot of term according to term number. + rpc GetTermSnapshot (GetTermSnapshotInput) returns (TermSnapshot) { + option (aelf.is_view) = true; + } + + // Get the count of miner. + rpc GetMinersCount (google.protobuf.Empty) returns (google.protobuf.Int32Value) { + option (aelf.is_view) = true; + } + + // Get the election result according to term id. + rpc GetElectionResult (GetElectionResultInput) returns (ElectionResult) { + option (aelf.is_view) = true; + } + + // Get the voter information according to voter public key. + rpc GetElectorVote (google.protobuf.StringValue) returns (ElectorVote) { + option (aelf.is_view) = true; + } + + // Gets the voter information including the active voting records (excluding withdrawn voting records.). + rpc GetElectorVoteWithRecords (google.protobuf.StringValue) returns (ElectorVote) { + option (aelf.is_view) = true; + } + + // Gets the voter information including the active and withdrawn voting records. + rpc GetElectorVoteWithAllRecords (google.protobuf.StringValue) returns (ElectorVote) { + option (aelf.is_view) = true; + } + + // Get voting information for candidate according to the public key of the candidate. + rpc GetCandidateVote (google.protobuf.StringValue) returns (CandidateVote) { + option (aelf.is_view) = true; + } + + // Get voting information for candidate according to the public key of the candidate. + rpc GetCandidateVoteWithRecords (google.protobuf.StringValue) returns (CandidateVote) { + option (aelf.is_view) = true; + } + + // Get voting information for candidate according to the public key of the candidate + // (including the active and withdrawn voting records). + rpc GetCandidateVoteWithAllRecords (google.protobuf.StringValue) returns (CandidateVote) { + option (aelf.is_view) = true; + } + + // Get the total number of voters. + rpc GetVotersCount (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get the total number of vote token. + rpc GetVotesAmount (google.protobuf.Empty) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Get candidate information according to the index and length. + rpc GetPageableCandidateInformation (PageInformation) returns (GetPageableCandidateInformationOutput) { + option (aelf.is_view) = true; + } + + // Get the voting item id of miner election. + rpc GetMinerElectionVotingItemId (google.protobuf.Empty) returns (aelf.Hash) { + option (aelf.is_view) = true; + } + + // Get the data center ranking list. + rpc GetDataCenterRankingList (google.protobuf.Empty) returns (DataCenterRankingList) { + option (aelf.is_view) = true; + } + + // Get the weight of vote interest. + rpc GetVoteWeightSetting (google.protobuf.Empty) returns (VoteWeightInterestList) { + option (aelf.is_view) = true; + } + + // Get the weight of lock time and votes in the calculation of voting weight. + rpc GetVoteWeightProportion (google.protobuf.Empty) returns (VoteWeightProportion) { + option (aelf.is_view) = true; + } + + // Used to calculate the bonus weights that users can get by voting. + rpc GetCalculateVoteWeight (VoteInformation) returns (google.protobuf.Int64Value){ + option (aelf.is_view) = true; + } + + // Query the controller for the weight of vote interest. + rpc GetVoteWeightInterestController (google.protobuf.Empty) returns (AuthorityInfo) { + option (aelf.is_view) = true; + } + + // Inspect the evil nodes included in the specified miners and return to the replacement node. + rpc GetMinerReplacementInformation (GetMinerReplacementInformationInput) returns (MinerReplacementInformation) { + option (aelf.is_view) = true; + } + + // Query candidate admin. + rpc GetCandidateAdmin (google.protobuf.StringValue) returns (aelf.Address) { + option (aelf.is_view) = true; + } + + // Query the newest pubkey of an old pubkey. + rpc GetNewestPubkey (google.protobuf.StringValue) returns (google.protobuf.StringValue) { + option (aelf.is_view) = true; + } + + // Query the old pubkey. + rpc GetReplacedPubkey (google.protobuf.StringValue) returns (google.protobuf.StringValue) { + option (aelf.is_view) = true; + } +} + +message InitialElectionContractInput { + // Minimum number of seconds for locking. + int64 minimum_lock_time = 1; + // Maximum number of seconds for locking. + int64 maximum_lock_time = 2; + // The current miner list. + repeated string miner_list = 3; + // The number of seconds per term. + int64 time_each_term = 4; + // The interval second that increases the number of miners. + int64 miner_increase_interval = 5; +} + +message GetTermSnapshotInput { + // The term number. + int64 term_number = 1; +} + +message UpdateCandidateInformationInput { + // The candidate public key. + string pubkey = 1; + // The number of blocks recently produced. + int64 recently_produced_blocks = 2; + // The number of time slots recently missed. + int64 recently_missed_time_slots = 3; + // Is it a evil node. If true will remove the candidate. + bool is_evil_node = 4; +} + +message UpdateMultipleCandidateInformationInput { + // The candidate information to update. + repeated UpdateCandidateInformationInput value = 1; +} + +message TakeElectionSnapshotInput { + // The term number to take snapshot. + int64 term_number = 1; + // The number of mined blocks of this term. + int64 mined_blocks = 2; + // The end round number of this term. + int64 round_number = 3; +} + +message VoteMinerInput { + // The candidate public key. + string candidate_pubkey = 1; + // The amount token to vote. + int64 amount = 2; + // The end timestamp of this vote. + google.protobuf.Timestamp end_timestamp = 3; + // Used to generate vote id. + aelf.Hash token = 4; +} + +message ChangeVotingOptionInput { + // The vote id to change. + aelf.Hash vote_id = 1; + // The new candidate public key. + string candidate_pubkey = 2; + // Tokens will be locked another previous locking time if this is true. + bool is_reset_voting_time = 3; +} + +message FixWelfareProfitInput { + repeated FixWelfareProfitInfo fix_info_list = 1; +} + +message FixWelfareProfitInfo { + aelf.Hash vote_id = 1; + int64 start_period = 2; + int64 end_period = 3; +} + +message UpdateTermNumberInput { + // The term number. + int64 term_number = 1; +} + +message GetElectionResultInput { + // The term number. + int64 term_number = 1; +} + +message ElectionResult { + // The term number + int64 term_number = 1; + // The election result, candidates’ public key -> number of votes. + map results = 2; + // Whether an election is currently being held. + bool is_active = 3; +} + +message ElectorVote { + // The active voting record ids. + repeated aelf.Hash active_voting_record_ids = 1; + // The voting record ids that were withdrawn. + repeated aelf.Hash withdrawn_voting_record_ids = 2; + // The total number of active votes. + int64 active_voted_votes_amount = 3; + // The total number of votes (including the number of votes withdrawn). + int64 all_voted_votes_amount = 4; + // The active voting records. + repeated ElectionVotingRecord active_voting_records = 5; + // The voting records that were withdrawn. + repeated ElectionVotingRecord withdrawn_votes_records = 6; + // Public key for voter. + bytes pubkey = 7; +} + +message CandidateVote { + // The active voting record ids obtained. + repeated aelf.Hash obtained_active_voting_record_ids = 1; + // The active voting record ids that were withdrawn. + repeated aelf.Hash obtained_withdrawn_voting_record_ids = 2; + // The total number of active votes obtained. + int64 obtained_active_voted_votes_amount = 3; + // The total number of votes obtained. + int64 all_obtained_voted_votes_amount = 4; + // The active voting records. + repeated ElectionVotingRecord obtained_active_voting_records = 5; + // The voting records that were withdrawn. + repeated ElectionVotingRecord obtained_withdrawn_votes_records = 6; + // Public key for candidate. + bytes pubkey = 7; +} + +message CandidateInformation { + // Candidate’s public key. + string pubkey = 1; + // The number of terms that the candidate is elected. + repeated int64 terms = 2; + // The number of blocks the candidate has produced. + int64 produced_blocks = 3; + // The time slot for which the candidate failed to produce blocks. + int64 missed_time_slots = 4; + // The count of continual appointment. + int64 continual_appointment_count = 5; + // The transaction id when the candidate announced. + aelf.Hash announcement_transaction_id = 6; + // Indicate whether the candidate can be elected in the current term. + bool is_current_candidate = 7; +} + +message CandidateDetail { + // The candidate information. + CandidateInformation candidate_information = 1; + // The number of votes a candidate has obtained. + int64 obtained_votes_amount = 2; +} + +message ElectionVotingRecord { + // The address of voter. + aelf.Address voter = 1; + // The public key of candidate. + string candidate = 2; + // Amount of voting. + int64 amount = 3; + // The term number of voting. + int64 term_number = 4; + // The vote id. + aelf.Hash vote_id = 5; + // Vote lock time. + int64 lock_time = 6; + // The unlock timestamp. + google.protobuf.Timestamp unlock_timestamp = 7; + // The withdraw timestamp. + google.protobuf.Timestamp withdraw_timestamp = 8; + // The vote timestamp. + google.protobuf.Timestamp vote_timestamp = 9; + // Indicates if the vote has been withdrawn. + bool is_withdrawn = 10; + // Vote weight for sharing bonus. + int64 weight = 11; + // Whether vote others. + bool is_change_target = 12; +} + +message PageInformation { + // The start index. + int32 start = 1; + // The number of records. + int32 length = 2; +} + +message PubkeyList { + // Candidates’ public keys + repeated bytes value = 1; +} + +message TermSnapshot { + // The end round number of this term. + int64 end_round_number = 1; + // The number of blocks mined in this term. + int64 mined_blocks = 2; + // The election result, candidates’ public key -> number of votes. + map election_result = 3; +} + +message UpdateMinersCountInput { + // The count of miner. + int32 miners_count = 1; +} + +message GetPageableCandidateInformationOutput { + // The details of the candidates. + repeated CandidateDetail value = 1; +} + +message SetTreasurySchemeIdsInput { + // The scheme id of treasury reward. + aelf.Hash treasury_hash = 1; + // The scheme id of welfare reward. + aelf.Hash welfare_hash = 2; + // The scheme id of subsidy reward. + aelf.Hash subsidy_hash = 3; + // The scheme id of welcome reward. + aelf.Hash welcome_hash = 4; + // The scheme id of flexible reward. + aelf.Hash flexible_hash = 5; +} + +message DataCenterRankingList { + // The top n * 5 candidates with vote amount, candidate public key -> vote amount. + map data_centers = 1; +} + +message VoteWeightInterest{ + // Number of days locked. + int32 day = 1; + // Locked interest. + int32 interest = 2; + int32 capital = 3; +} + +message VoteWeightInterestList { + // The weight of vote interest. + repeated VoteWeightInterest vote_weight_interest_infos = 1; +} + +message VoteWeightProportion { + // The weight of lock time. + int32 time_proportion = 1; + // The weight of the votes cast. + int32 amount_proportion = 2; +} + +message VoteInformation{ + // Amount of voting. + int64 amount = 1; + // Vote lock time. + int64 lock_time = 2; +} + +message GetMinerReplacementInformationInput { + // The current miner list to inspect. + repeated string current_miner_list = 1; +} + +message MinerReplacementInformation { + // The alternative candidate public keys. + repeated string alternative_candidate_pubkeys = 1; + // The evil miner public keys. + repeated string evil_miner_pubkeys = 2; +} + +message ReplaceCandidatePubkeyInput { + string old_pubkey = 1; + string new_pubkey = 2; +} + +message SetCandidateAdminInput { + string pubkey = 1; + aelf.Address admin = 2; +} + +message EvilMinerDetected { + option (aelf.is_event) = true; + // The public key of evil miner. + string pubkey = 1; +} + +message CandidatePubkeyReplaced { + option (aelf.is_event) = true; + string old_pubkey = 1; + string new_pubkey = 2; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/kernel.proto b/src/AElf.Client.Protobuf/Protobuf/kernel.proto new file mode 100644 index 0000000..4a9c404 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/kernel.proto @@ -0,0 +1,183 @@ +syntax = "proto3"; + +package aelf; + +import "google/protobuf/timestamp.proto"; +import "aelf/core.proto"; + +option csharp_namespace = "AElf.Kernel"; + +enum TransactionStatus { + UNKNOWN_TRANSACTION_STATUS = 0; + TRANSACTION_EXECUTING = 1; + TRANSACTION_EXECUTED = 2; +} + +message StateValue { + bytes current_value = 1; + bytes original_value = 2; +} + +message StateChange { + StatePath state_path = 1; + StateValue state_value = 2; +} + +// For failed transactions, its status follows the Min of +// its own status and its inline transactions' +enum ExecutionStatus { + UNDEFINED = 0; + // Successful => + EXECUTED = 1; + + // Failed => + // Infrastructure reasons + CANCELED = -1; + SYSTEM_ERROR = -2; + + // Contract reasons + CONTRACT_ERROR = -10; + EXCEEDED_MAX_CALL_DEPTH = -11; + + // Pre-failed + PREFAILED = -99; + + // Post-failed + POSTFAILED = -199; +} + +message TransactionTrace { + Hash transaction_id = 1; + bytes return_value = 2; + string error = 3; + repeated Transaction pre_transactions = 4; + repeated TransactionTrace pre_traces = 5; + repeated Transaction inline_transactions = 6; + repeated TransactionTrace inline_traces = 7; + repeated Transaction post_transactions = 8; + repeated TransactionTrace post_traces = 9; + repeated LogEvent logs = 10; + int64 elapsed = 11; + ExecutionStatus execution_status = 12; + TransactionExecutingStateSet state_set = 13; +} + +message ExecutionReturnSet { + Hash transaction_id = 1; + TransactionResultStatus status = 2; + map state_changes = 3; + map state_accesses = 4; + bytes bloom = 5; + bytes return_value = 6; + map state_deletes = 7; + TransactionResult transaction_result = 8; +} + +message BlockHeaderList { + repeated BlockHeader headers = 1; +} + +message BlockHeader { + int32 version = 1; + int32 chain_id = 2; + Hash previous_block_hash = 3; + Hash merkle_tree_root_of_transactions = 4; + Hash merkle_tree_root_of_world_state = 5; + bytes bloom = 6; + int64 height = 7; + map extra_data = 8; + google.protobuf.Timestamp time = 9; + Hash merkle_tree_root_of_transaction_status = 10; + bytes signer_pubkey = 9999; + bytes signature = 10000; +} + +message BlockBody { + repeated Hash transaction_ids = 1; +} + +message Block { + BlockHeader header = 1; + BlockBody body = 2; +} + +message VersionedState { + string key = 1; + bytes value = 2; + int64 block_height = 3; + Hash block_hash = 4; + Hash origin_block_hash = 5; +} + +message BlockStateSet { + Hash block_hash = 1; + Hash previous_hash = 2; + int64 block_height = 3; + map changes = 4; + repeated string deletes = 5; + map block_executed_data = 6; +} + +enum ChainStateMergingStatus { + COMMON = 0; + MERGING = 1; + MERGED = 2; +} + +message ChainStateInfo { + int32 chain_id = 1; + Hash block_hash = 2; + int64 block_height = 3; + Hash merging_block_hash = 4; + ChainStateMergingStatus status = 5; +} + +enum ChainBlockLinkExecutionStatus { + EXECUTION_NONE = 0; + EXECUTION_SUCCESS = 1; + EXECUTION_FAILED = 2; +} + +message ChainBlockLink { + Hash block_hash = 1; + int64 height = 2; + Hash previous_block_hash = 3; + ChainBlockLinkExecutionStatus execution_status = 4; + bool is_irreversible_block = 5; + bool is_linked = 6; + bool is_light_block = 7; //no block body +} + +message Chain { + int32 id = 1; + Hash genesis_block_hash = 2; + Hash longest_chain_hash = 3; + int64 longest_chain_height = 4; + map branches = 5; + map not_linked_blocks = 6; + Hash last_irreversible_block_hash = 7; + int64 last_irreversible_block_height = 8; + Hash best_chain_hash = 9; + int64 best_chain_height = 10; +} + +message ChainBlockIndex { + Hash block_hash = 1; +} + +message BlockIndex{ + Hash block_hash = 1; + int64 block_height = 2; +} + +message TransactionBlockIndex { + Hash block_hash = 1; + int64 block_height = 2; + repeated BlockIndex previous_execution_block_index_list = 3; +} + +message SmartContractAddress{ + Address address = 1; + Hash block_hash = 2; + int64 block_height = 3; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/parliament_contract.proto b/src/AElf.Client.Protobuf/Protobuf/parliament_contract.proto new file mode 100644 index 0000000..c7a8936 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/parliament_contract.proto @@ -0,0 +1,148 @@ +/** + * Parliament contract. + */ +syntax = "proto3"; + +package Parliament; + +import "acs3.proto"; +import public "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +option csharp_namespace = "AElf.Contracts.Parliament"; + +service ParliamentContract { + + option (aelf.csharp_state) = "AElf.Contracts.Parliament.ParliamentState"; + + // Initialize parliament proposer whitelist and create the first parliament organization + // with specific proposer_authority_required. + rpc Initialize(InitializeInput) returns (google.protobuf.Empty) { + } + + // Create an organization and return its address. + rpc CreateOrganization (CreateOrganizationInput) returns (aelf.Address) { + } + + // Batch approval proposal. + rpc ApproveMultiProposals(ProposalIdList) returns (google.protobuf.Empty){ + } + + // Creates an organization by system contract and return its address. + rpc CreateOrganizationBySystemContract(CreateOrganizationBySystemContractInput) returns (aelf.Address){ + } + + // Creates an organization to handle emergency events. + rpc CreateEmergencyResponseOrganization (google.protobuf.Empty) returns (google.protobuf.Empty) { + } + + // Get the organization according to the organization address. + rpc GetOrganization (aelf.Address) returns (Organization) { + option (aelf.is_view) = true; + } + + // Get the default organization address. + rpc GetDefaultOrganizationAddress (google.protobuf.Empty) returns (aelf.Address) { + option (aelf.is_view) = true; + } + + // Validates if the provided address is a parliament member. + rpc ValidateAddressIsParliamentMember(aelf.Address) returns (google.protobuf.BoolValue){ + option (aelf.is_view) = true; + } + + // Returns the list of whitelisted proposers. + rpc GetProposerWhiteList(google.protobuf.Empty) returns (acs3.ProposerWhiteList){ + option (aelf.is_view) = true; + } + + // Filter still pending ones not yet voted by the sender from provided proposals. + rpc GetNotVotedPendingProposals(ProposalIdList) returns (ProposalIdList){ + option (aelf.is_view) = true; + } + + // Filter not yet voted ones by the sender from provided proposals. + rpc GetNotVotedProposals(ProposalIdList) returns (ProposalIdList){ + option (aelf.is_view) = true; + } + + // Calculates with input and return the organization address. + rpc CalculateOrganizationAddress(CreateOrganizationInput) returns (aelf.Address){ + option (aelf.is_view) = true; + } + + rpc GetEmergencyResponseOrganizationAddress (google.protobuf.Empty) returns (aelf.Address) { + option (aelf.is_view) = true; + } +} + +message CreateOrganizationInput { + // The threshold for releasing the proposal. + acs3.ProposalReleaseThreshold proposal_release_threshold = 1; + // Setting this to false will allow anyone creating proposals. + bool proposer_authority_required = 2; + // Setting this to true can allow parliament member to create proposals. + bool parliament_member_proposing_allowed = 3; + // The creation token is for organization address generation. + aelf.Hash creation_token = 4; +} + +message Organization { + // Indicates if proposals need authority to be created. + bool proposer_authority_required = 1; + // The organization address. + aelf.Address organization_address = 2; + // The organization id. + aelf.Hash organization_hash = 3; + // The threshold for releasing the proposal. + acs3.ProposalReleaseThreshold proposal_release_threshold = 4; + // Indicates if parliament member can propose to this organization. + bool parliament_member_proposing_allowed = 5; + // The creation token is for organization address generation. + aelf.Hash creation_token = 6; +} + +message ProposalInfo { + // The proposal ID. + aelf.Hash proposal_id = 1; + // The method that this proposal will call when being released. + string contract_method_name = 2; + // The address of the target contract. + aelf.Address to_address = 3; + // The parameters of the release transaction. + bytes params = 4; + // The date at which this proposal will expire. + google.protobuf.Timestamp expired_time = 5; + // The address of the proposer of this proposal. + aelf.Address proposer = 6; + // The address of this proposals organization. + aelf.Address organization_address = 7; + // Address list of approved. + repeated aelf.Address approvals = 8; + // Address list of rejected. + repeated aelf.Address rejections = 9; + // Address list of abstained. + repeated aelf.Address abstentions = 10; + // Url is used for proposal describing. + string proposal_description_url = 11; +} + +message InitializeInput{ + // Privileged proposer would be the first address in parliament proposer whitelist. + aelf.Address privileged_proposer = 1; + // The setting indicates if proposals need authority to be created for first/default parliament organization. + bool proposer_authority_required = 2; +} + +message ProposalIdList{ + // The list of proposal ids. + repeated aelf.Hash proposal_ids = 1; +} + +message CreateOrganizationBySystemContractInput { + // The parameters of creating organization. + CreateOrganizationInput organization_creation_input = 1; + // The organization address callback method which replies the organization address to caller contract. + string organization_address_feedback_method = 2; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/profit_contract.proto b/src/AElf.Client.Protobuf/Protobuf/profit_contract.proto new file mode 100644 index 0000000..745406d --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/profit_contract.proto @@ -0,0 +1,370 @@ +/** + * Profit contract. + */ +syntax = "proto3"; + +package Profit; + +import "aelf/core.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +option csharp_namespace = "AElf.Contracts.Profit"; + +service ProfitContract { + option (aelf.csharp_state) = "AElf.Contracts.Profit.ProfitContractState"; + + // Create a scheme for profit distribution, and return the created scheme id. + rpc CreateScheme (CreateSchemeInput) returns (aelf.Hash) { + } + + // Add beneficiary to scheme. + rpc AddBeneficiary (AddBeneficiaryInput) returns (google.protobuf.Empty) { + } + + // Remove beneficiary from scheme. + rpc RemoveBeneficiary (RemoveBeneficiaryInput) returns (google.protobuf.Empty) { + } + + // Batch add beneficiary to scheme. + rpc AddBeneficiaries (AddBeneficiariesInput) returns (google.protobuf.Empty) { + } + + // Batch remove beneficiary from scheme. + rpc RemoveBeneficiaries (RemoveBeneficiariesInput) returns (google.protobuf.Empty) { + } + + rpc FixProfitDetail (FixProfitDetailInput) returns (google.protobuf.Empty) { + } + + // Contribute profit to a scheme. + rpc ContributeProfits (ContributeProfitsInput) returns (google.protobuf.Empty) { + } + + // The beneficiary draws tokens from the scheme. + rpc ClaimProfits (ClaimProfitsInput) returns (google.protobuf.Empty) { + } + + // Distribute profits to schemes, including its sub scheme according to period and token symbol, + // should be called by the manager. + rpc DistributeProfits (DistributeProfitsInput) returns (google.protobuf.Empty) { + } + + // Add sub scheme to a scheme. + // This will effectively add the specified sub-scheme as a beneficiary of the parent scheme. + rpc AddSubScheme (AddSubSchemeInput) returns (google.protobuf.Empty) { + } + + // Remove sub scheme from a scheme. + rpc RemoveSubScheme (RemoveSubSchemeInput) returns (google.protobuf.Empty) { + } + + // Reset the manager of a scheme. + rpc ResetManager (ResetManagerInput) returns (google.protobuf.Empty) { + } + + // Get all schemes managed by the specified manager. + rpc GetManagingSchemeIds (GetManagingSchemeIdsInput) returns (CreatedSchemeIds) { + option (aelf.is_view) = true; + } + + // Get scheme according to scheme id. + rpc GetScheme (aelf.Hash) returns (Scheme) { + option (aelf.is_view) = true; + } + + // Get the virtual address of the number of period of the scheme. + rpc GetSchemeAddress (SchemePeriod) returns (aelf.Address) { + option (aelf.is_view) = true; + } + + // Query the distributed profit information for the specified period. + rpc GetDistributedProfitsInfo (SchemePeriod) returns (DistributedProfitsInfo) { + option (aelf.is_view) = true; + } + + // Query the beneficiary's profit information on the scheme. + rpc GetProfitDetails (GetProfitDetailsInput) returns (ProfitDetails) { + option (aelf.is_view) = true; + } + + // Query the amount of profit according to token symbol. (up to 10 periods). + rpc GetProfitAmount (GetProfitAmountInput) returns (google.protobuf.Int64Value) { + option (aelf.is_view) = true; + } + + // Query all profit (up to 10 periods). + rpc GetProfitsMap (ClaimProfitsInput) returns (ReceivedProfitsMap) { + option (aelf.is_view) = true; + } +} + +message CreateSchemeInput { + // Period of profit distribution. + int64 profit_receiving_due_period_count = 1; + // Whether all the schemes balance will be distributed during distribution each period. + bool is_release_all_balance_every_time_by_default = 2; + // Delay distribute period. + int32 delay_distribute_period_count = 3; + // The manager of this scheme, the default is the creator. + aelf.Address manager = 4; + // Whether you can directly remove the beneficiary. + bool can_remove_beneficiary_directly = 5; + // Use to generate scheme id. + aelf.Hash token = 6; +} + +message Scheme { + // The virtual address of the scheme. + aelf.Address virtual_address = 1; + // The total weight of the scheme. + int64 total_shares = 2; + // The manager of the scheme. + aelf.Address manager = 3; + // The current period. + int64 current_period = 4; + // Sub schemes information. + repeated SchemeBeneficiaryShare sub_schemes = 5; + // Whether you can directly remove the beneficiary. + bool can_remove_beneficiary_directly = 6; + // Period of profit distribution. + int64 profit_receiving_due_period_count = 7; + // Whether all the schemes balance will be distributed during distribution each period. + bool is_release_all_balance_every_time_by_default = 8; + // The is of the scheme. + aelf.Hash scheme_id = 9; + // Delay distribute period. + int32 delay_distribute_period_count = 10; + // Record the scheme's current total share for deferred distribution of benefits, period -> total shares. + map cached_delay_total_shares = 11; + // The received token symbols. + repeated string received_token_symbols = 12; +} + +message SchemeBeneficiaryShare { + // The id of the sub scheme. + aelf.Hash scheme_id = 1; + // The weight of the sub scheme. + int64 shares = 2; +} + +message AddBeneficiaryInput { + // The scheme id. + aelf.Hash scheme_id = 1; + // The beneficiary information. + BeneficiaryShare beneficiary_share = 2; + // The end period which the beneficiary receives the profit. + int64 start_period = 3; + int64 end_period = 4; + bool is_fix_profit_detail = 5; + aelf.Hash profit_detail_id = 6; +} + +message FixProfitDetailInput { + aelf.Hash scheme_id = 1; + BeneficiaryShare beneficiary_share = 2; + int64 start_period = 3; + int64 end_period = 4; + aelf.Hash profit_detail_id = 5; +} + +message RemoveBeneficiaryInput { + // The address of beneficiary. + aelf.Address beneficiary = 1; + // The scheme id. + aelf.Hash scheme_id = 2; + aelf.Hash profit_detail_id = 3; +} + +message AddBeneficiariesInput { + // The scheme id. + aelf.Hash scheme_id = 1; + // The beneficiary information. + repeated BeneficiaryShare beneficiary_shares = 2; + // The end period which the beneficiary receives the profit. + int64 end_period = 3; +} + +message RemoveBeneficiariesInput { + // The addresses of beneficiary. + repeated aelf.Address beneficiaries = 1; + // The scheme id. + aelf.Hash scheme_id = 2; +} + +message BeneficiaryShare { + // The address of beneficiary. + aelf.Address beneficiary = 1; + // The profit weight of the beneficiary in the scheme. + int64 shares = 2; +} + +message ClaimProfitsInput { + // The scheme id. + aelf.Hash scheme_id = 1; + // The address of beneficiary. + aelf.Address beneficiary = 2; +} + +message DistributeProfitsInput { + // The scheme id to distribute. + aelf.Hash scheme_id = 1; + // The period number to distribute, should be the current period. + int64 period = 2; + // The amount to distribute, symbol -> amount. + map amounts_map = 3; +} + +message ProfitDetails { + // The profit information. + repeated ProfitDetail details = 1; +} + +message ProfitDetail { + // The start period number. + int64 start_period = 1; + // The end period number. + int64 end_period = 2; + // The weight of the proceeds on the current period of the scheme. + int64 shares = 3; + // The last period number that the beneficiary received the profit. + int64 last_profit_period = 4; + // Whether the weight has been removed. + bool is_weight_removed = 5; + aelf.Hash id = 6; +} + +message ContributeProfitsInput { + // The scheme id to contribute. + aelf.Hash scheme_id = 1; + // The amount to contribute. + int64 amount = 2; + // The number of periods in which the income is used for dividends. + int64 period = 3; + // The token symbol to contribute. + string symbol = 4; +} + +message AddSubSchemeInput { + // The parent scheme id. + aelf.Hash scheme_id = 1; + // The sub scheme id. + aelf.Hash sub_scheme_id = 2; + // The profit weight of sub scheme. + int64 sub_scheme_shares = 3; +} + +message RemoveSubSchemeInput { + // The parent scheme id. + aelf.Hash scheme_id = 1; + // The sub scheme id. + aelf.Hash sub_scheme_id = 2; +} + +message DistributedProfitsInfo { + // The total amount of shares in this scheme at the current period. + int64 total_shares = 1; + // The contributed amount in this scheme at the current period. + map amounts_map = 2;//Token symbol -> Amount + // Whether released. + bool is_released = 3; +} + +message CreatedSchemeIds { + // The scheme ids. + repeated aelf.Hash scheme_ids = 1; +} + +message GetManagingSchemeIdsInput { + // The manager address. + aelf.Address manager = 1; +} + +message SchemePeriod { + // The scheme id. + aelf.Hash scheme_id = 1; + // The period number. + int64 period = 2; +} + +message GetProfitDetailsInput { + // The scheme id. + aelf.Hash scheme_id = 1; + // The address of beneficiary. + aelf.Address beneficiary = 2; +} + +message ResetManagerInput { + // The scheme id. + aelf.Hash scheme_id = 1; + // The address of new manager. + aelf.Address new_manager = 2; +} + +message GetProfitAmountInput { + // The scheme id. + aelf.Hash scheme_id = 1; + // The token symbol. + string symbol = 2; + // The beneficiary's address. + aelf.Address beneficiary = 3; +} + +message ReceivedProfitsMap { + // The collection of profits received, token symbol -> amount. + map value = 1; +} + +message ReceivedProfitsMapList { + repeated ReceivedProfitsMap value = 1; +} + +message SchemeCreated { + option (aelf.is_event) = true; + // The virtual address of the created scheme. + aelf.Address virtual_address = 1; + // The manager of the created scheme. + aelf.Address manager = 2; + // Period of profit distribution. + int64 profit_receiving_due_period_count = 3; + // Whether all the schemes balance will be distributed during distribution each period. + bool is_release_all_balance_every_time_by_default = 4; + // The id of the created scheme. + aelf.Hash scheme_id = 5; +} + +message ProfitsClaimed { + option (aelf.is_event) = true; + // The beneficiary's address claimed. + aelf.Address beneficiary = 1; + // The token symbol claimed. + string symbol = 2; + // The amount claimed. + int64 amount = 3; + // The period number claimed. + int64 period = 4; + // The shares of the claimer. + int64 claimer_shares = 5; + // The total shares at the current period. + int64 total_shares = 6; +} + +message ProfitDetailAdded { + option (aelf.is_event) = true; + int64 start_period = 1; + int64 end_period = 2; + int64 shares = 3; + bool is_weight_removed = 4; + aelf.Address beneficiary = 5; +} + +message DistributedPeriodInfoChanged { + option (aelf.is_event) = true; + aelf.Hash scheme_id = 1; + int64 period = 2; + int64 total_shares = 3; + ReceivedProfitsMapList profits_map_list = 4; + bool is_released = 5; + aelf.Address virtual_address = 6; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/referendum_contract.proto b/src/AElf.Client.Protobuf/Protobuf/referendum_contract.proto new file mode 100644 index 0000000..82af016 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/referendum_contract.proto @@ -0,0 +1,129 @@ +/** + * Referendum contract. + */ +syntax = "proto3"; + +package Referendum; + +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "aelf/core.proto"; +import "acs3.proto"; + +option csharp_namespace = "AElf.Contracts.Referendum"; + +service ReferendumContract { + + option (aelf.csharp_state) = "AElf.Contracts.Referendum.ReferendumState"; + + // Unlock the token used for voting according to proposal id. + rpc ReclaimVoteToken (aelf.Hash) returns (google.protobuf.Empty) { + } + + // Create an organization and return its address. + rpc CreateOrganization (CreateOrganizationInput) returns (aelf.Address) { + } + + // Creates an organization by system contract and return its address. + rpc CreateOrganizationBySystemContract (CreateOrganizationBySystemContractInput) returns (aelf.Address) { + } + + // Get the organization according to the organization address. + rpc GetOrganization (aelf.Address) returns (Organization) { + option (aelf.is_view) = true; + } + + // Calculate the input and return the organization address. + rpc CalculateOrganizationAddress (CreateOrganizationInput) returns (aelf.Address) { + option (aelf.is_view) = true; + } + + // Get the virtual address of a proposal based on the proposal id. + rpc GetProposalVirtualAddress (aelf.Hash) returns (aelf.Address) { + } +} + +message CreateOrganizationInput { + // The token used during proposal operations. + string token_symbol = 1; + // The threshold for releasing the proposal. + acs3.ProposalReleaseThreshold proposal_release_threshold = 2; + // The proposer whitelist. + acs3.ProposerWhiteList proposer_white_list = 3; + // The creation token is for organization address generation. + aelf.Hash creation_token = 4; +} + +message Organization { + // The threshold for releasing the proposal. + acs3.ProposalReleaseThreshold proposal_release_threshold = 1; + // The token used during proposal operations. + string token_symbol = 2; + // The address of organization. + aelf.Address organization_address = 3; + // The organizations id. + aelf.Hash organization_hash = 4; + // The proposer whitelist. + acs3.ProposerWhiteList proposer_white_list = 5; + // The creation token is for organization address generation. + aelf.Hash creation_token = 6; +} + +message Receipt { + // The amount of token locked. + int64 amount = 1; + // The symbol of token locked. + string token_symbol = 2; + // The lock id. + aelf.Hash lock_id = 3; +} + +message ProposalInfo { + // The proposal ID. + aelf.Hash proposal_id = 1; + // The method that this proposal will call when being released. + string contract_method_name = 2; + // The address of the target contract. + aelf.Address to_address = 3; + // The parameters of the release transaction. + bytes params = 4; + // The date at which this proposal will expire. + google.protobuf.Timestamp expired_time = 5; + // The address of the proposer of this proposal. + aelf.Address proposer = 6; + // The address of this proposals organization. + aelf.Address organization_address = 7; + // The count of approved. + int64 approval_count = 8; + // The count of rejected. + int64 rejection_count = 9; + // The count of abstained. + int64 abstention_count = 10; + // Url is used for proposal describing. + string proposal_description_url = 11; +} + +message CreateOrganizationBySystemContractInput { + // The parameters of creating organization. + CreateOrganizationInput organization_creation_input = 1; + // The organization address callback method which replies the organization address to caller contract. + string organization_address_feedback_method = 2; +} + +message ReferendumReceiptCreated { + option (aelf.is_event) = true; + // The id of the proposal. + aelf.Hash proposal_id = 1; + // The sender address. + aelf.Address address = 2; + // The symbol of token locked. + string symbol = 3; + // The amount of token locked. + int64 amount = 4; + // The type of receipt(Approve, Reject or Abstain). + string receipt_type = 5; + // The timestamp of this method call. + google.protobuf.Timestamp time = 6; + // The address of the organization. + aelf.Address organization_address = 7 [(aelf.is_indexed) = true]; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/token_contract.proto b/src/AElf.Client.Protobuf/Protobuf/token_contract.proto new file mode 100644 index 0000000..93d1433 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/token_contract.proto @@ -0,0 +1,739 @@ +/** + * MultiToken contract. + */ +syntax = "proto3"; + +package token; + +import "aelf/core.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +option csharp_namespace = "AElf.Contracts.MultiToken"; + +service TokenContract { + // Create a new token. + rpc Create (CreateInput) returns (google.protobuf.Empty) { + } + + // Issuing some amount of tokens to an address is the action of increasing that addresses balance + // for the given token. The total amount of issued tokens must not exceed the total supply of the token + // and only the issuer (creator) of the token can issue tokens. + // Issuing tokens effectively increases the circulating supply. + rpc Issue (IssueInput) returns (google.protobuf.Empty) { + } + + // Transferring tokens simply is the action of transferring a given amount of tokens from one address to another. + // The origin or source address is the signer of the transaction. + // The balance of the sender must be higher than the amount that is transferred. + rpc Transfer (TransferInput) returns (google.protobuf.Empty) { + } + + // The TransferFrom action will transfer a specified amount of tokens from one address to another. + // For this operation to succeed the from address needs to have approved (see allowances) enough tokens + // to Sender of this transaction. If successful the amount will be removed from the allowance. + rpc TransferFrom (TransferFromInput) returns (google.protobuf.Empty) { + } + + // The approve action increases the allowance from the Sender to the Spender address, + // enabling the Spender to call TransferFrom. + rpc Approve (ApproveInput) returns (google.protobuf.Empty) { + } + + // This is the reverse operation for Approve, it will decrease the allowance. + rpc UnApprove (UnApproveInput) returns (google.protobuf.Empty) { + } + + // This method can be used to lock tokens. + rpc Lock (LockInput) returns (google.protobuf.Empty) { + } + + // This is the reverse operation of locking, it un-locks some previously locked tokens. + rpc Unlock (UnlockInput) returns (google.protobuf.Empty) { + } + + // This action will burn the specified amount of tokens, removing them from the token’s Supply. + rpc Burn (BurnInput) returns (google.protobuf.Empty) { + } + + // Change the issuer of the specified token. Only the original issuer can change it. + rpc ChangeTokenIssuer (ChangeTokenIssuerInput) returns (google.protobuf.Empty) { + } + + // Set the primary token of side chain. + rpc SetPrimaryTokenSymbol (SetPrimaryTokenSymbolInput) returns (google.protobuf.Empty) { + } + + // This interface is used for cross-chain transfer. + rpc CrossChainTransfer (CrossChainTransferInput) returns (google.protobuf.Empty) { + } + + // This method is used to receive cross-chain transfers. + rpc CrossChainReceiveToken (CrossChainReceiveTokenInput) returns (google.protobuf.Empty) { + } + + // The side chain creates tokens. + rpc CrossChainCreateToken(CrossChainCreateTokenInput) returns (google.protobuf.Empty) { + } + + // When the side chain is started, the side chain is initialized with the parent chain information. + rpc InitializeFromParentChain (InitializeFromParentChainInput) returns (google.protobuf.Empty) { + } + + // Handle the transaction fees charged by ChargeTransactionFees. + rpc ClaimTransactionFees (TotalTransactionFeesMap) returns (google.protobuf.Empty) { + } + + // Used to collect transaction fees. + rpc ChargeTransactionFees (ChargeTransactionFeesInput) returns (ChargeTransactionFeesOutput) { + } + + // Check the token threshold. + rpc CheckThreshold (CheckThresholdInput) returns (google.protobuf.Empty) { + } + + // Initialize coefficients of every type of tokens supporting charging fee. + rpc InitialCoefficients (google.protobuf.Empty) returns (google.protobuf.Empty){ + } + + // Processing resource token received. + rpc DonateResourceToken (TotalResourceTokensMaps) returns (google.protobuf.Empty) { + } + + // A transaction resource fee is charged to implement the ACS8 standards. + rpc ChargeResourceToken (ChargeResourceTokenInput) returns (google.protobuf.Empty) { + } + + // Verify that the resource token are sufficient. + rpc CheckResourceToken (google.protobuf.Empty) returns (google.protobuf.Empty) { + } + + // Set the list of tokens to pay transaction fees. + rpc SetSymbolsToPayTxSizeFee (SymbolListToPayTxSizeFee) returns (google.protobuf.Empty){ + } + + // Update the coefficient of the transaction fee calculation formula. + rpc UpdateCoefficientsForSender (UpdateCoefficientsInput) returns (google.protobuf.Empty) { + } + + // Update the coefficient of the transaction fee calculation formula. + rpc UpdateCoefficientsForContract (UpdateCoefficientsInput) returns (google.protobuf.Empty) { + } + + // This method is used to initialize the governance organization for some functions, + // including: the coefficient of the user transaction fee calculation formula, + // the coefficient of the contract developer resource fee calculation formula, and the side chain rental fee. + rpc InitializeAuthorizedController(google.protobuf.Empty) returns (google.protobuf.Empty){ + } + + // Query token information. + rpc GetTokenInfo (GetTokenInfoInput) returns (TokenInfo) { + option (aelf.is_view) = true; + } + + // Query native token information. + rpc GetNativeTokenInfo (google.protobuf.Empty) returns (TokenInfo) { + option (aelf.is_view) = true; + } + + // Query resource token information. + rpc GetResourceTokenInfo (google.protobuf.Empty) returns (TokenInfoList) { + option (aelf.is_view) = true; + } + + // Query the balance at the specified address. + rpc GetBalance (GetBalanceInput) returns (GetBalanceOutput) { + option (aelf.is_view) = true; + } + + // Query the account's allowance for other addresses + rpc GetAllowance (GetAllowanceInput) returns (GetAllowanceOutput) { + option (aelf.is_view) = true; + } + + // Check whether the token is in the whitelist of an address, + // which can be called TransferFrom to transfer the token under the condition of not being credited. + rpc IsInWhiteList (IsInWhiteListInput) returns (google.protobuf.BoolValue) { + option (aelf.is_view) = true; + } + + // Query the information for a lock. + rpc GetLockedAmount (GetLockedAmountInput) returns (GetLockedAmountOutput) { + option (aelf.is_view) = true; + } + + // Query the address of receiving token in cross-chain transfer. + rpc GetCrossChainTransferTokenContractAddress (GetCrossChainTransferTokenContractAddressInput) returns (aelf.Address) { + option (aelf.is_view) = true; + } + + // Query the name of the primary Token. + rpc GetPrimaryTokenSymbol (google.protobuf.Empty) returns (google.protobuf.StringValue) { + option (aelf.is_view) = true; + } + + // Query the coefficient of the transaction fee calculation formula. + rpc GetCalculateFeeCoefficientsForContract (google.protobuf.Int32Value) returns (CalculateFeeCoefficients) { + option (aelf.is_view) = true; + } + + // Query the coefficient of the transaction fee calculation formula. + rpc GetCalculateFeeCoefficientsForSender (google.protobuf.Empty) returns (CalculateFeeCoefficients) { + option (aelf.is_view) = true; + } + + // Query tokens that can pay transaction fees. + rpc GetSymbolsToPayTxSizeFee (google.protobuf.Empty) returns (SymbolListToPayTxSizeFee){ + option (aelf.is_view) = true; + } + + // Query the hash of the last input of ClaimTransactionFees. + rpc GetLatestTotalTransactionFeesMapHash (google.protobuf.Empty) returns (aelf.Hash){ + option (aelf.is_view) = true; + } + + // Query the hash of the last input of DonateResourceToken. + rpc GetLatestTotalResourceTokensMapsHash (google.protobuf.Empty) returns (aelf.Hash){ + option (aelf.is_view) = true; + } + rpc IsTokenAvailableForMethodFee (google.protobuf.StringValue) returns (google.protobuf.BoolValue) { + option (aelf.is_view) = true; + } +} + +message TokenInfo { + // The symbol of the token.f + string symbol = 1; + // The full name of the token. + string token_name = 2; + // The current supply of the token. + int64 supply = 3; + // The total supply of the token. + int64 total_supply = 4; + // The precision of the token. + int32 decimals = 5; + // The address that created the token. + aelf.Address issuer = 6; + // A flag indicating if this token is burnable. + bool is_burnable = 7; + // The chain id of the token. + int32 issue_chain_id = 8; + // The amount of issued tokens. + int64 issued = 9; +} + +message CreateInput { + // The symbol of the token. + string symbol = 1; + // The full name of the token. + string token_name = 2; + // The total supply of the token. + int64 total_supply = 3; + // The precision of the token + int32 decimals = 4; + // The address that created the token. + aelf.Address issuer = 5; + // A flag indicating if this token is burnable. + bool is_burnable = 6; + // A whitelist address list used to lock tokens. + repeated aelf.Address lock_white_list = 7; + // The chain id of the token. + int32 issue_chain_id = 8; +} + +message SetPrimaryTokenSymbolInput { + // The symbol of the token. + string symbol = 1; +} + +message IssueInput { + // The token symbol to issue. + string symbol = 1; + // The token amount to issue. + int64 amount = 2; + // The memo. + string memo = 3; + // The target address to issue. + aelf.Address to = 4; +} + +message TransferInput { + // The receiver of the token. + aelf.Address to = 1; + // The token symbol to transfer. + string symbol = 2; + // The amount to to transfer. + int64 amount = 3; + // The memo. + string memo = 4; +} + +message LockInput { + // The one want to lock his token. + aelf.Address address = 1; + // Id of the lock. + aelf.Hash lock_id = 2; + // The symbol of the token to lock. + string symbol = 3; + // a memo. + string usage = 4; + // The amount of tokens to lock. + int64 amount = 5; +} + +message UnlockInput { + // The one want to un-lock his token. + aelf.Address address = 1; + // Id of the lock. + aelf.Hash lock_id = 2; + // The symbol of the token to un-lock. + string symbol = 3; + // a memo. + string usage = 4; + // The amount of tokens to un-lock. + int64 amount = 5; +} + +message TransferFromInput { + // The source address of the token. + aelf.Address from = 1; + // The destination address of the token. + aelf.Address to = 2; + // The symbol of the token to transfer. + string symbol = 3; + // The amount to transfer. + int64 amount = 4; + // The memo. + string memo = 5; +} + +message ApproveInput { + // The address that allowance will be increased. + aelf.Address spender = 1; + // The symbol of token to approve. + string symbol = 2; + // The amount of token to approve. + int64 amount = 3; +} + +message UnApproveInput { + // The address that allowance will be decreased. + aelf.Address spender = 1; + // The symbol of token to un-approve. + string symbol = 2; + // The amount of token to un-approve. + int64 amount = 3; +} + +message BurnInput { + // The symbol of token to burn. + string symbol = 1; + // The amount of token to burn. + int64 amount = 2; +} + +message ChargeResourceTokenInput { + // Collection of charge resource token, Symbol->Amount. + map cost_dic = 1; + // The sender of the transaction. + aelf.Address caller = 2; +} + +message TransactionFeeBill { + // The transaction fee dictionary, Symbol->fee. + map fees_map = 1; +} + +message CheckThresholdInput { + // The sender of the transaction. + aelf.Address sender = 1; + // The threshold to set, Symbol->Threshold. + map symbol_to_threshold = 2; + // Whether to check the allowance. + bool is_check_allowance = 3; +} + +message GetTokenInfoInput { + // The symbol of token. + string symbol = 1; +} + +message GetBalanceInput { + // The symbol of token. + string symbol = 1; + // The target address of the query. + aelf.Address owner = 2; +} + +message GetBalanceOutput { + // The symbol of token. + string symbol = 1; + // The target address of the query. + aelf.Address owner = 2; + // The balance of the owner. + int64 balance = 3; +} + +message GetAllowanceInput { + // The symbol of token. + string symbol = 1; + // The address of the token owner. + aelf.Address owner = 2; + // The address of the spender. + aelf.Address spender = 3; +} + +message GetAllowanceOutput { + // The symbol of token. + string symbol = 1; + // The address of the token owner. + aelf.Address owner = 2; + // The address of the spender. + aelf.Address spender = 3; + // The amount of allowance. + int64 allowance = 4; +} + +message CrossChainTransferInput { + // The receiver of transfer. + aelf.Address to = 1; + // The symbol of token. + string symbol = 2; + // The amount of token to transfer. + int64 amount = 3; + // The memo. + string memo = 4; + // The destination chain id. + int32 to_chain_id = 5; + // The chain id of the token. + int32 issue_chain_id = 6; +} + +message CrossChainReceiveTokenInput { + // The source chain id. + int32 from_chain_id = 1; + // The height of the transfer transaction. + int64 parent_chain_height = 2; + // The raw bytes of the transfer transaction. + bytes transfer_transaction_bytes = 3; + // The merkle path created from the transfer transaction. + aelf.MerklePath merkle_path = 4; +} + +message IsInWhiteListInput { + // The symbol of token. + string symbol = 1; + // The address to check. + aelf.Address address = 2; +} + +message SymbolToPayTxSizeFee{ + // The symbol of token. + string token_symbol = 1; + // The charge weight of primary token. + int32 base_token_weight = 2; + // The new added token charge weight. For example, the charge weight of primary Token is set to 1. + // The newly added token charge weight is set to 10. If the transaction requires 1 unit of primary token, + // the user can also pay for 10 newly added tokens. + int32 added_token_weight = 3; +} + +message SymbolListToPayTxSizeFee{ + // Transaction fee token information. + repeated SymbolToPayTxSizeFee symbols_to_pay_tx_size_fee = 1; +} + +message ChargeTransactionFeesInput { + // The method name of transaction. + string method_name = 1; + // The contract address of transaction. + aelf.Address contract_address = 2; + // The amount of transaction size fee. + int64 transaction_size_fee = 3; + // Transaction fee token information. + repeated SymbolToPayTxSizeFee symbols_to_pay_tx_size_fee = 4; +} + +message ChargeTransactionFeesOutput { + // Whether the charge was successful. + bool success = 1; + // The charging information. + string charging_information = 2; +} + +message ExtraTokenListModified { + option (aelf.is_event) = true; + // Transaction fee token information. + SymbolListToPayTxSizeFee symbol_list_to_pay_tx_size_fee = 1; +} + +message GetLockedAmountInput { + // The address of the lock. + aelf.Address address = 1; + // The token symbol. + string symbol = 2; + // The id of the lock. + aelf.Hash lock_id = 3; +} + +message GetLockedAmountOutput { + // The address of the lock. + aelf.Address address = 1; + // The token symbol. + string symbol = 2; + // The id of the lock. + aelf.Hash lock_id = 3; + // The locked amount. + int64 amount = 4; +} + +message TokenInfoList { + // List of token information. + repeated TokenInfo value = 1; +} + +message GetCrossChainTransferTokenContractAddressInput { + // The chain id. + int32 chainId = 1; +} + +message CrossChainCreateTokenInput { + // The chain id of the chain on which the token was created. + int32 from_chain_id = 1; + // The height of the transaction that created the token. + int64 parent_chain_height = 2; + // The transaction that created the token. + bytes transaction_bytes = 3; + // The merkle path created from the transaction that created the transaction. + aelf.MerklePath merkle_path = 4; +} + +message InitializeFromParentChainInput { + // The amount of resource. + map resource_amount = 1; + // The token contract addresses. + map registered_other_token_contract_addresses = 2; + // The creator the side chain. + aelf.Address creator = 3; +} + +message UpdateCoefficientsInput { + // The specify pieces gonna update. + repeated int32 piece_numbers = 1; + // Coefficients of one single type. + CalculateFeeCoefficients coefficients = 2; +} + +enum FeeTypeEnum { + READ = 0; + STORAGE = 1; + WRITE = 2; + TRAFFIC = 3; + TX = 4; +} + +message CalculateFeePieceCoefficients { + // Coefficients of one single piece. + // The first char is its type: liner / power. + // The second char is its piece upper bound. + repeated int32 value = 1; +} + +message CalculateFeeCoefficients { + // The resource fee type, like READ, WRITE, etc. + int32 fee_token_type = 1; + // Coefficients of one single piece. + repeated CalculateFeePieceCoefficients piece_coefficients_list = 2; +} + +message AllCalculateFeeCoefficients { + // The coefficients of fee Calculation. + repeated CalculateFeeCoefficients value = 1; +} + +message TotalTransactionFeesMap +{ + // Token dictionary that charge transaction fee, Symbol->Amount. + map value = 1; + // The hash of the block processing the transaction. + aelf.Hash block_hash = 2; + // The height of the block processing the transaction. + int64 block_height = 3; +} + +message TotalResourceTokensMaps { + // Resource tokens to charge. + repeated ContractTotalResourceTokens value = 1; + // The hash of the block processing the transaction. + aelf.Hash block_hash = 2; + // The height of the block processing the transaction. + int64 block_height = 3; +} + +message ContractTotalResourceTokens { + // The contract address. + aelf.Address contract_address = 1; + // Resource tokens to charge. + TotalResourceTokensMap tokens_map = 2; +} + +message TotalResourceTokensMap +{ + // Resource token dictionary, Symbol->Amount. + map value = 1; +} + +message ChangeTokenIssuerInput +{ + // The token symbol. + string symbol = 1; + // The new token issuer for change. + aelf.Address new_token_Issuer = 2; +} + +message Transferred { + option (aelf.is_event) = true; + // The source address of the transferred token. + aelf.Address from = 1 [(aelf.is_indexed) = true]; + // The destination address of the transferred token. + aelf.Address to = 2 [(aelf.is_indexed) = true]; + // The symbol of the transferred token. + string symbol = 3 [(aelf.is_indexed) = true]; + // The amount of the transferred token. + int64 amount = 4; + // The memo. + string memo = 5; +} + +message Approved { + option (aelf.is_event) = true; + // The address of the token owner. + aelf.Address owner = 1 [(aelf.is_indexed) = true]; + // The address that allowance be increased. + aelf.Address spender = 2 [(aelf.is_indexed) = true]; + // The symbol of approved token. + string symbol = 3 [(aelf.is_indexed) = true]; + // The amount of approved token. + int64 amount = 4; +} + +message UnApproved { + option (aelf.is_event) = true; + // The address of the token owner. + aelf.Address owner = 1 [(aelf.is_indexed) = true]; + // The address that allowance be decreased. + aelf.Address spender = 2 [(aelf.is_indexed) = true]; + // The symbol of un-approved token. + string symbol = 3 [(aelf.is_indexed) = true]; + // The amount of un-approved token. + int64 amount = 4; +} + +message Burned +{ + option (aelf.is_event) = true; + // The address who wants to burn token. + aelf.Address burner = 1 [(aelf.is_indexed) = true]; + // The symbol of burned token. + string symbol = 2 [(aelf.is_indexed) = true]; + // The amount of burned token. + int64 amount = 3; +} + +message ChainPrimaryTokenSymbolSet { + option (aelf.is_event) = true; + // The symbol of token. + string token_symbol = 1; +} + + +message CalculateFeeAlgorithmUpdated { + option (aelf.is_event) = true; + // All calculate fee coefficients after modification. + AllCalculateFeeCoefficients all_type_fee_coefficients = 1; +} + +message RentalCharged { + option (aelf.is_event) = true; + // The symbol of rental fee charged. + string symbol = 1; + // The amount of rental fee charged. + int64 amount = 2; +} + +message RentalAccountBalanceInsufficient { + option (aelf.is_event) = true; + // The symbol of insufficient rental account balance. + string symbol = 1; + // The balance of the account. + int64 amount = 2; +} + +message TokenCreated { + option (aelf.is_event) = true; + // The symbol of the token. + string symbol = 1; + // The full name of the token. + string token_name = 2; + // The total supply of the token. + int64 total_supply = 3; + // The precision of the token. + int32 decimals = 4; + // The address that created the token. + aelf.Address issuer = 5; + // A flag indicating if this token is burnable. + bool is_burnable = 6; + // The chain id of the token. + int32 issue_chain_id = 7; +} + +message Issued { + option (aelf.is_event) = true; + // The symbol of issued token. + string symbol = 1; + // The amount of issued token. + int64 amount = 2; + // The memo. + string memo = 3; + // The issued target address. + aelf.Address to = 4; +} + +message CrossChainTransferred { + option (aelf.is_event) = true; + // The source address of the transferred token. + aelf.Address from = 1; + // The destination address of the transferred token. + aelf.Address to = 2; + // The symbol of the transferred token. + string symbol = 3; + // The amount of the transferred token. + int64 amount = 4; + // The memo. + string memo = 5; + // The destination chain id. + int32 to_chain_id = 6; + // The chain id of the token. + int32 issue_chain_id = 7; +} + +message CrossChainReceived { + option (aelf.is_event) = true; + // The source address of the transferred token. + aelf.Address from = 1; + // The destination address of the transferred token. + aelf.Address to = 2; + // The symbol of the received token. + string symbol = 3; + // The amount of the received token. + int64 amount = 4; + // The memo. + string memo = 5; + // The destination chain id. + int32 from_chain_id = 6; + // The chain id of the token. + int32 issue_chain_id = 7; + // The parent chain height of the transfer transaction. + int64 parent_chain_height = 8; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/token_converter_contract.proto b/src/AElf.Client.Protobuf/Protobuf/token_converter_contract.proto new file mode 100644 index 0000000..af6e99c --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/token_converter_contract.proto @@ -0,0 +1,193 @@ +/** + * TokenConvert contract. + */ +syntax = "proto3"; + +package TokenConverter; + +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; +import "aelf/core.proto"; +import "authority_info.proto"; + +option csharp_namespace = "AElf.Contracts.TokenConverter"; + +service TokenConverterContract { + + option (aelf.csharp_state) = "AElf.Contracts.TokenConverter.TokenConverterContractState"; + + // Initialize TokenConvert contract. + rpc Initialize (InitializeInput) returns (google.protobuf.Empty) { + } + + rpc SetConnector (Connector) returns (google.protobuf.Empty) { + } + + // After establishing bancor model of token and base token, you can buy token through this method. + rpc Buy (BuyInput) returns (google.protobuf.Empty) { + } + + // After establishing bancor model of token and base token, you can sell token through this method. + rpc Sell (SellInput) returns (google.protobuf.Empty) { + } + + // Set the fee rate for buy/sell (fee amount = cost * feeRate). + rpc SetFeeRate (google.protobuf.StringValue) returns (google.protobuf.Empty) { + } + + // Before calling the EnableConnector, the connector controller can update the pair connector through this method. + rpc UpdateConnector(Connector) returns (google.protobuf.Empty){ + } + + // Add a pair connector for new token and the base token. + rpc AddPairConnector(PairConnectorParam) returns (google.protobuf.Empty){ + } + + // After adding a pair, you need to call this method to enable it before buy and sell token. + rpc EnableConnector (ToBeConnectedTokenInfo) returns (google.protobuf.Empty) { + } + + // Set the governance authority information for TokenConvert contract. + rpc ChangeConnectorController (AuthorityInfo) returns (google.protobuf.Empty) { + } + + // Query the pair connector according to token symbol. + rpc GetPairConnector (TokenSymbol) returns (PairConnector) { + option (aelf.is_view) = true; + } + + // Query the fee rate for buy/sell. + rpc GetFeeRate (google.protobuf.Empty) returns (google.protobuf.StringValue) { + option (aelf.is_view) = true; + } + + // Query the symbol of base token. + rpc GetBaseTokenSymbol (google.protobuf.Empty) returns (TokenSymbol) { + option (aelf.is_view) = true; + } + + // Query how much the base token need be deposited before enabling the connector. + rpc GetNeededDeposit(ToBeConnectedTokenInfo) returns (DepositInfo) { + option (aelf.is_view) = true; + } + + // Query how much the base token have been deposited. + rpc GetDepositConnectorBalance(google.protobuf.StringValue) returns (google.protobuf.Int64Value){ + option (aelf.is_view) = true; + } + + // Query the governance authority information for TokenConvert contract. + rpc GetControllerForManageConnector (google.protobuf.Empty) returns (AuthorityInfo) { + option (aelf.is_view) = true; + } + + // Query whether the token can be sold. + rpc IsSymbolAbleToSell (google.protobuf.StringValue) returns (google.protobuf.BoolValue) { + option (aelf.is_view) = true; + } +} + +message Connector { + // The token symbol. + string symbol = 1; + // The virtual balance for base token. + int64 virtual_balance = 2; + // The calculated weight value for this Connector. + string weight = 3; + // Whether to use Virtual Balance. + bool is_virtual_balance_enabled = 4; + // Whether the connector is enabled. + bool is_purchase_enabled = 5; + // Indicates its related connector, the pair connector includes a new created token connector and the base token connector. + string related_symbol = 6; + // Indicates if the connector is base token connector. + bool is_deposit_account = 7; +} + +message TokenSymbol { + // The token symbol. + string symbol = 1; +} + +message InitializeInput { + // Base token symbol, default is the native token symbol. + string base_token_symbol = 1; + // The fee rate for buy/sell. + string fee_rate = 2; + // The default added connectors. + repeated Connector connectors = 3; +} + +message BuyInput { + // The token symbol you want to buy. + string symbol = 1; + // The amount you want to buy. + int64 amount = 2; + // Limit of cost. If the token required for buy exceeds this value, the buy will be abandoned. + // And 0 is no limit. + int64 pay_limit = 3; +} + +message SellInput { + // The token symbol you want to sell. + string symbol = 1; + // The amount you want to sell. + int64 amount = 2; + // Limits on tokens obtained by selling. If the token obtained is less than this value, the sale will be abandoned. + // And 0 is no limit. + int64 receive_limit = 3; +} + +message TokenBought { + option (aelf.is_event) = true; + // The token symbol bought. + string symbol = 1 [(aelf.is_indexed) = true]; + // The amount bought. + int64 bought_amount = 2; + // The total cost of the base token. + int64 base_amount = 3; + // The fee amount. + int64 fee_amount =4; +} + +message TokenSold { + option (aelf.is_event) = true; + // The token symbol sold. + string symbol = 1 [(aelf.is_indexed) = true]; + // The amount sold. + int64 sold_amount = 2; + // The total received of the base token. + int64 base_amount = 3; + // The fee amount. + int64 fee_amount =4; +} +message PairConnectorParam { + // The token symbol. + string resource_connector_symbol = 1; + // The weight value of this token in the Bancor model. + string resource_weight = 2; + // This token corresponds to the value of base token. + int64 native_virtual_balance = 3; + // The weight value of base token in Bancor model. + string native_weight = 4; +} + +message ToBeConnectedTokenInfo{ + // The token symbol. + string token_symbol = 1; + // Specifies the number of tokens to convert to the TokenConvert contract. + int64 amount_to_token_convert = 2; +} +message DepositInfo{ + // How much more base Token is needed as the deposit. + int64 need_amount = 1; + // How many tokens are not on the TokenConvert address. + int64 amount_out_of_token_convert = 2; +} +message PairConnector{ + // The connector of the specified token. + Connector resource_connector = 1; + // The related connector. + Connector deposit_connector = 2; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/token_holder_contract.proto b/src/AElf.Client.Protobuf/Protobuf/token_holder_contract.proto new file mode 100644 index 0000000..53fd16c --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/token_holder_contract.proto @@ -0,0 +1,132 @@ +/** + * TokenHolder contract. + */ +syntax = "proto3"; + +package TokenHolder; + +import "aelf/core.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +option csharp_namespace = "AElf.Contracts.TokenHolder"; + +service TokenHolderContract { + + option (aelf.csharp_state) = "AElf.Contracts.TokenHolder.TokenHolderContractState"; + + // Create a scheme for distributing bonus. + rpc CreateScheme (CreateTokenHolderProfitSchemeInput) returns (google.protobuf.Empty) { + } + + // Add a beneficiary to a scheme. + rpc AddBeneficiary (AddTokenHolderBeneficiaryInput) returns (google.protobuf.Empty) { + } + + // Removes a beneficiary from a scheme. + // Note: amount > 0: update the weight of the beneficiary, amount = 0: remove the beneficiary. + rpc RemoveBeneficiary (RemoveTokenHolderBeneficiaryInput) returns (google.protobuf.Empty) { + } + + // Contribute profit to a scheme. + rpc ContributeProfits (ContributeProfitsInput) returns (google.protobuf.Empty) { + } + + // To distribute the profits of the scheme, the stakeholders of the project may go to receive dividends. + rpc DistributeProfits (DistributeProfitsInput) returns (google.protobuf.Empty) { + } + + // The user registers a bonus project. + rpc RegisterForProfits (RegisterForProfitsInput) returns (google.protobuf.Empty) { + } + + // After the lockup time expires, the user can withdraw token. + rpc Withdraw (aelf.Address) returns (google.protobuf.Empty) { + } + + // After DistributeProfits the holder can get his dividend. + rpc ClaimProfits (ClaimProfitsInput) returns (google.protobuf.Empty) { + } + + // Query the details of the specified scheme. + rpc GetScheme (aelf.Address) returns (TokenHolderProfitScheme) { + option (aelf.is_view) = true; + } + + // Query the dividends available to the holder. + rpc GetProfitsMap (ClaimProfitsInput) returns (ReceivedProfitsMap) { + option (aelf.is_view) = true; + } +} + +message CreateTokenHolderProfitSchemeInput { + // The token symbol. + string symbol = 1; + // Minimum lock time for holding token. + int64 minimum_lock_minutes = 2; + // Threshold setting for releasing dividends. + map auto_distribute_threshold = 3; +} + +message AddTokenHolderBeneficiaryInput { + // Beneficiary's address. + aelf.Address beneficiary = 1; + // The weight of the beneficiary's dividends in the scheme. + int64 shares = 2; +} + +message RemoveTokenHolderBeneficiaryInput { + // Beneficiary's address. + aelf.Address beneficiary = 1; + // The amount of weights to remove. + int64 amount = 2; +} + +message ContributeProfitsInput { + // The manager of the scheme. + aelf.Address scheme_manager = 1; + // The amount of token to contribute. + int64 amount = 2; + // The symbol of token to contribute. + string symbol = 3; +} + +message DistributeProfitsInput { + // The manager of the scheme. + aelf.Address scheme_manager = 1; + // The token to distribute, symbol -> amount. + map amounts_map = 2; +} + +message RegisterForProfitsInput { + // The manager of the scheme. + aelf.Address scheme_manager = 1; + // The amount of token holding. + int64 amount = 2; +} + +message ClaimProfitsInput { + // The manager of the scheme. + aelf.Address scheme_manager = 1; + // Beneficiary's address. + aelf.Address beneficiary = 2; +} + +message TokenHolderProfitScheme { + // The token symbol. + string symbol = 1; + // The scheme id. + aelf.Hash scheme_id = 2; + // The current dividend period. + int64 period = 3; + // Minimum lock time for holding token. + int64 minimum_lock_minutes = 4; + // Threshold setting for releasing dividends. + map auto_distribute_threshold = 5; +} + +message ReceivedProfitsMap { + // The amount of token the beneficiary can get, symbol -> amount. + map value = 1; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/transaction_fee.proto b/src/AElf.Client.Protobuf/Protobuf/transaction_fee.proto new file mode 100644 index 0000000..ed4ed8b --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/transaction_fee.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; + +package aelf; + +import "aelf/core.proto"; +import "aelf/options.proto"; + +option csharp_namespace = "AElf.Contracts.MultiToken"; + +service TransactionFee { +} + +// Messages + +message TransactionSizeFeeSymbols +{ + repeated TransactionSizeFeeSymbol transaction_size_fee_symbol_list = 1; +} + +message TransactionSizeFeeSymbol +{ + string token_symbol = 1; + int32 base_token_weight = 2; + int32 added_token_weight = 3; +} + +// Events + +message TransactionFeeCharged { + option (aelf.is_event) = true; + string symbol = 1; + int64 amount = 2; +} + +message ResourceTokenCharged { + option (aelf.is_event) = true; + string symbol = 1; + int64 amount = 2; + aelf.Address contract_address = 3; +} + +message ResourceTokenOwned { + option (aelf.is_event) = true; + string symbol = 1; + int64 amount = 2; + aelf.Address contract_address = 3; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/treasury_contract.proto b/src/AElf.Client.Protobuf/Protobuf/treasury_contract.proto new file mode 100644 index 0000000..0ce87cf --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/treasury_contract.proto @@ -0,0 +1,149 @@ +/** + * Treasury contract. + */ +syntax = "proto3"; + +package Treasury; + +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; +import "aelf/core.proto"; +import "authority_info.proto"; + +option csharp_namespace = "AElf.Contracts.Treasury"; + +service TreasuryContract { + option (aelf.csharp_state) = "AElf.Contracts.Treasury.TreasuryContractState"; + + // Initialize treasury contract. + rpc InitialTreasuryContract (google.protobuf.Empty) returns (google.protobuf.Empty) { + } + + // Initialize the sub-item of the bonus scheme. + rpc InitialMiningRewardProfitItem (google.protobuf.Empty) returns (google.protobuf.Empty) { + } + + // Donate all tokens owned by the sender. + rpc DonateAll (DonateAllInput) returns (google.protobuf.Empty) { + } + + // Set the dividend weight of the sub-item of the dividend item. + rpc SetDividendPoolWeightSetting (DividendPoolWeightSetting) returns (google.protobuf.Empty){ + } + + // Set the miner reward weight. + rpc SetMinerRewardWeightSetting (MinerRewardWeightSetting) returns (google.protobuf.Empty){ + } + + // Set the reward for mining. + rpc UpdateMiningReward (google.protobuf.Int64Value) returns (google.protobuf.Empty){ + } + + // Change the governance authority information for treasury contract. + rpc ChangeTreasuryController (AuthorityInfo) returns (google.protobuf.Empty) { + } + + // AEDPoS Contract can notify Treasury Contract to aware miner replacement happened. + rpc RecordMinerReplacement (RecordMinerReplacementInput) returns (google.protobuf.Empty) { + } + + // Used to estimate the revenue weight of 10000 tokens voted by users. + rpc GetWelfareRewardAmountSample (GetWelfareRewardAmountSampleInput) returns (GetWelfareRewardAmountSampleOutput) { + option (aelf.is_view) = true; + } + + // Get the scheme id of treasury. + rpc GetTreasurySchemeId (google.protobuf.Empty) returns (aelf.Hash) { + option (aelf.is_view) = true; + } + + // Query the weight percentage of dividend pool items. + rpc GetDividendPoolWeightProportion (google.protobuf.Empty) returns (DividendPoolWeightProportion) { + option (aelf.is_view) = true; + } + + // Query the weight percentage of the dividend item for miner. + rpc GetMinerRewardWeightProportion (google.protobuf.Empty) returns (MinerRewardWeightProportion) { + option (aelf.is_view) = true; + } + + // Query the governance authority information. + rpc GetTreasuryController (google.protobuf.Empty) returns (AuthorityInfo) { + option (aelf.is_view) = true; + } +} + +message GetWelfareRewardAmountSampleInput { + // Token lock time. + repeated int64 value = 1; +} + +message GetWelfareRewardAmountSampleOutput { + // The weight calculated. + repeated int64 value = 1; +} + +message DonateAllInput { + // The token symbol to donate. + string symbol = 1; +} + +message MinerReElectionInformation { + // The reappointment information for miner. + map continual_appointment_times = 1; +} + +message DividendPoolWeightSetting { + // The dividend weight for citizen. + int32 citizen_welfare_weight = 1; + // The dividend weight for backup nodes. + int32 backup_subsidy_weight = 2; + // The dividend weight for miners. + int32 miner_reward_weight = 3; +} + +message MinerRewardWeightSetting { + // The dividend weight for all current miners. + int32 basic_miner_reward_weight = 1; + // The dividend weight for new miners. + int32 welcome_reward_weight = 2; + // The dividend weight for the flexible scheme. + int32 flexible_reward_weight = 3; +} + +message SchemeProportionInfo { + // The scheme id. + aelf.Hash scheme_id = 1; + // Dividend weight percentage. + int32 proportion = 2; +} + +message DividendPoolWeightProportion { + // The proportion of citizen welfare. + SchemeProportionInfo citizen_welfare_proportion_info = 1; + // The proportion of candidate nodes. + SchemeProportionInfo backup_subsidy_proportion_info = 2; + // The proportion of miner + SchemeProportionInfo miner_reward_proportion_info = 3; +} + +message MinerRewardWeightProportion { + // The proportion of the basic income of the miner. + SchemeProportionInfo basic_miner_reward_proportion_info = 1; + // The proportion of the vote of the miner. + SchemeProportionInfo welcome_reward_proportion_info = 2; + // The proportion of the reappointment of the miner. + SchemeProportionInfo flexible_reward_proportion_info = 3; +} + +message RecordMinerReplacementInput { + string old_pubkey = 1; + string new_pubkey = 2; + int64 current_term_number = 3; + bool is_old_pubkey_evil = 4; +} + +message StringList { + repeated string value = 1; +} \ No newline at end of file diff --git a/src/AElf.Client.Protobuf/Protobuf/vote_contract.proto b/src/AElf.Client.Protobuf/Protobuf/vote_contract.proto new file mode 100644 index 0000000..2c7e0e6 --- /dev/null +++ b/src/AElf.Client.Protobuf/Protobuf/vote_contract.proto @@ -0,0 +1,311 @@ +/** + * Vote contract. + */ +syntax = "proto3"; + +package Vote; + +import "aelf/core.proto"; +import "google/protobuf/timestamp.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; + +option csharp_namespace = "AElf.Contracts.Vote"; + +service VoteContract { + option (aelf.csharp_state) = "AElf.Contracts.Vote.VoteContractState"; + + // Create a voting activity. + rpc Register (VotingRegisterInput) returns (google.protobuf.Empty) { + } + + // After successfully creating a voting activity, others are able to vote. + rpc Vote (VoteInput) returns (google.protobuf.Empty) { + } + + // A voter can withdraw the token after the lock time. + rpc Withdraw (WithdrawInput) returns (google.protobuf.Empty) { + } + + // Save the result of the specified number of votes and generates a new round votes. + rpc TakeSnapshot (TakeSnapshotInput) returns (google.protobuf.Empty) { + } + + // Add an option to a voting activity. + rpc AddOption (AddOptionInput) returns (google.protobuf.Empty) { + } + + // Remove an option from a voting activity. + rpc RemoveOption (RemoveOptionInput) returns (google.protobuf.Empty) { + } + + // Add multiple options to a voting activity. + rpc AddOptions (AddOptionsInput) returns (google.protobuf.Empty) { + } + + // Remove multiple options from a voting activity. + rpc RemoveOptions (RemoveOptionsInput) returns (google.protobuf.Empty) { + } + + // Get a voting activity information. + rpc GetVotingItem (GetVotingItemInput) returns (VotingItem) { + option (aelf.is_view) = true; + } + + // Get a voting result according to the provided voting activity id and snapshot number. + rpc GetVotingResult (GetVotingResultInput) returns (VotingResult) { + option (aelf.is_view) = true; + } + + // Gets the latest result according to the voting activity id. + rpc GetLatestVotingResult (aelf.Hash) returns (VotingResult) { + option (aelf.is_view) = true; + } + + // Get the voting record according to vote id. + rpc GetVotingRecord (aelf.Hash) returns (VotingRecord) { + option (aelf.is_view) = true; + } + + // Get the voting record according to vote ids. + rpc GetVotingRecords (GetVotingRecordsInput) returns (VotingRecords) { + option (aelf.is_view) = true; + } + + // Get all voted information according to voter address. + rpc GetVotedItems (aelf.Address) returns (VotedItems) { + option (aelf.is_view) = true; + } + + // Get the vote ids according to voting activity id. + rpc GetVotingIds (GetVotingIdsInput) returns (VotedIds) { + option (aelf.is_view) = true; + } +} + +message VotingRegisterInput { + // The start time of the voting. + google.protobuf.Timestamp start_timestamp = 1; + // The end time of the voting. + google.protobuf.Timestamp end_timestamp = 2; + // The token symbol which will be accepted. + string accepted_currency = 3; + // Whether the vote will lock token. + bool is_lock_token = 4; + // The total number of snapshots of the vote. + int64 total_snapshot_number = 5; + // The list of options. + repeated string options = 6; +} + +message VotingItem { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The token symbol which will be accepted. + string accepted_currency = 2; + // Whether the vote will lock token. + bool is_lock_token = 3; + // The current snapshot number. + int64 current_snapshot_number = 4; + // The total snapshot number. + int64 total_snapshot_number = 5; + // The list of options. + repeated string options = 6; + // The register time of the voting activity. + google.protobuf.Timestamp register_timestamp = 7; + // The start time of the voting. + google.protobuf.Timestamp start_timestamp = 8; + // The end time of the voting. + google.protobuf.Timestamp end_timestamp = 9; + // The start time of current round of the voting. + google.protobuf.Timestamp current_snapshot_start_timestamp = 10; + // The sponsor address of the voting activity. + aelf.Address sponsor = 11; +} + +message VoteInput { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The address of voter. + aelf.Address voter = 2; + // The amount of vote. + int64 amount = 3; + // The option to vote. + string option = 4; + // The vote id. + aelf.Hash vote_id = 5; + // Whether vote others. + bool is_change_target = 6; +} + +message WithdrawInput { + // The vote id. + aelf.Hash vote_id = 1; +} + +message GetVotingResultInput { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The snapshot number. + int64 snapshot_number = 2; +} + +message VotingResult { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The voting result, option -> amount of votes, + map results = 2; + // The snapshot number. + int64 snapshot_number = 3; + // The total number of voters. + int64 voters_count = 4; + // The start time of this snapshot. + google.protobuf.Timestamp snapshot_start_timestamp = 5; + // The end time of this snapshot. + google.protobuf.Timestamp snapshot_end_timestamp = 6; + // Total votes received during the process of this snapshot. + int64 votes_amount = 7; +} + +message TakeSnapshotInput { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The snapshot number to take. + int64 snapshot_number = 2; +} + +message VotingRecord { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The address of voter. + aelf.Address voter = 2; + // The snapshot number. + int64 snapshot_number = 3; + // The amount of vote. + int64 amount = 4; + // The time of withdraw. + google.protobuf.Timestamp withdraw_timestamp = 5; + // The time of vote. + google.protobuf.Timestamp vote_timestamp = 6; + // Whether the vote had been withdrawn. + bool is_withdrawn = 7; + // The option voted. + string option = 8; + // Whether vote others. + bool is_change_target = 9; +} + +message AddOptionInput { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The new option to add. + string option = 2; +} + +message RemoveOptionInput { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The option to remove. + string option = 2; +} + +message AddOptionsInput { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The new options to add. + repeated string options = 2; +} + +message RemoveOptionsInput { + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The options to remove. + repeated string options = 2; +} + +message VotedItems { + // The voted ids. + map voted_item_vote_ids = 1; +} + +message VotedIds { + // The active vote ids. + repeated aelf.Hash active_votes = 1; + // The withdrawn vote ids. + repeated aelf.Hash withdrawn_votes = 2; +} + +message GetVotingIdsInput { + // The address of voter. + aelf.Address voter = 1; + // The voting activity id. + aelf.Hash voting_item_id = 2; +} + +message GetVotingItemInput { + // The voting activity id. + aelf.Hash voting_item_id = 1; +} + +message GetVotingRecordsInput { + // The vote ids. + repeated aelf.Hash ids = 1; +} + +message VotingRecords { + // The voting records. + repeated VotingRecord records = 1; +} + +message Voted { + option (aelf.is_event) = true; + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The address of voter. + aelf.Address voter = 2; + // The snapshot number. + int64 snapshot_number = 3; + // The amount of vote. + int64 amount = 4; + // The time of vote. + google.protobuf.Timestamp vote_timestamp = 5; + // The option voted. + string option = 6; + // The vote id. + aelf.Hash vote_id = 7; +} + +message Withdrawn { + option (aelf.is_event) = true; + // The vote id. + aelf.Hash vote_id = 1; + aelf.Hash voting_item_id = 2; + int64 amount = 3; + string option = 4; + aelf.Address voter = 5; +} + +message VotingItemRegistered { + option (aelf.is_event) = true; + // The voting activity id. + aelf.Hash voting_item_id = 1; + // The token symbol which will be accepted. + string accepted_currency = 2; + // Whether the vote will lock token. + bool is_lock_token = 3; + // The current snapshot number. + int64 current_snapshot_number = 4; + // The total number of snapshots of the vote. + int64 total_snapshot_number = 5; + // The register time of the voting activity. + google.protobuf.Timestamp register_timestamp = 6; + // The start time of the voting. + google.protobuf.Timestamp start_timestamp = 7; + // The end time of the voting. + google.protobuf.Timestamp end_timestamp = 8; + // The start time of current round of the voting. + google.protobuf.Timestamp current_snapshot_start_timestamp = 9; + // The sponsor address of the voting activity. + aelf.Address sponsor = 10; +} \ No newline at end of file diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj new file mode 100644 index 0000000..bf0886e --- /dev/null +++ b/src/AElf.Client/AElf.Client.csproj @@ -0,0 +1,19 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + diff --git a/src/AElf.Client/AElfClient.Block.cs b/src/AElf.Client/AElfClient.Block.cs new file mode 100644 index 0000000..b6c7301 --- /dev/null +++ b/src/AElf.Client/AElfClient.Block.cs @@ -0,0 +1,44 @@ +using AElf.Client.Dto; +using AElf.Client.Services; + +namespace AElf.Client; + +public partial class AElfClient : IBlockAppService +{ + /// + /// Get height of the current chain. + /// + /// Height + public async Task GetBlockHeightAsync() + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/blockHeight"); + return await _httpService.GetResponseAsync(url); + } + + /// + /// Get information of a block by given block hash. Optional whether to include transaction information. + /// + /// + /// + /// Block information + public async Task GetBlockByHashAsync(string blockHash, bool includeTransactions = false) + { + AssertValidHash(blockHash); + var url = GetRequestUrl(_baseUrl, + $"api/blockChain/block?blockHash={blockHash}&includeTransactions={includeTransactions}"); + return await _httpService.GetResponseAsync(url); + } + + /// + /// Get information of a block by specified height. Optional whether to include transaction information. + /// + /// + /// + /// Block information + public async Task GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false) + { + var url = GetRequestUrl(_baseUrl, + $"api/blockChain/blockByHeight?blockHeight={blockHeight}&includeTransactions={includeTransactions}"); + return await _httpService.GetResponseAsync(url); + } +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClient.Chain.cs b/src/AElf.Client/AElfClient.Chain.cs new file mode 100644 index 0000000..e42eb0f --- /dev/null +++ b/src/AElf.Client/AElfClient.Chain.cs @@ -0,0 +1,69 @@ +using AElf.Client.Dto; + +namespace AElf.Client; + +public partial class AElfClient : IChainAppService +{ + /// + /// Get the current status of the block chain. + /// + /// Description of current status + public async Task GetChainStatusAsync() + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/chainStatus"); + var chainStatus = await _httpService.GetResponseAsync(url); + if (chainStatus == null) + { + throw new AElfClientException("Failed to get chain status"); + } + + return chainStatus; + } + + /// + /// Get the definitions of proto-buff related to a contract. + /// + /// + /// Definitions of proto-buff + public async Task GetContractFileDescriptorSetAsync(string? address) + { + AssertValidAddress(address); + var url = GetRequestUrl(_baseUrl, $"api/blockChain/contractFileDescriptorSet?address={address}"); + var set = await _httpService.GetResponseAsync(url); + if (set == null) + { + throw new AElfClientException("Failed to get chain status"); + } + + return set; + } + + /// + /// Gets the status information of the task queue. + /// + /// Information of the task queue + public async Task> GetTaskQueueStatusAsync() + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/taskQueueStatus"); + + var taskQueueInfoList = await _httpService.GetResponseAsync>(url); + if (taskQueueInfoList == null) + { + throw new AElfClientException("Failed to get chain status"); + } + + return taskQueueInfoList; + } + + /// + /// Get id of the chain. + /// + /// ChainId + public async Task GetChainIdAsync() + { + var chainStatus = await GetChainStatusAsync(); + var base58ChainId = chainStatus.ChainId; + var chainId = ChainHelper.ConvertBase58ToChainId(base58ChainId); + return chainId; + } +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClient.Client.cs b/src/AElf.Client/AElfClient.Client.cs new file mode 100644 index 0000000..776fed0 --- /dev/null +++ b/src/AElf.Client/AElfClient.Client.cs @@ -0,0 +1,249 @@ +using AElf.Client.Dto; +using AElf.Client.Extensions; +using AElf.Client.Model; +using AElf.Client.Services; +using AElf.Cryptography; +using AElf.Cryptography.ECDSA; +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; + +namespace AElf.Client; + +public partial class AElfClient : IClientService +{ + /// + /// Verify whether this sdk successfully connects the chain. + /// + /// IsConnected or not + public async Task IsConnectedAsync() + { + try + { + var chainStatus = await GetChainStatusAsync(); + return chainStatus != null; + } + catch (Exception) + { + return false; + } + } + + /// + /// Get the address of genesis contract. + /// + /// Address + public async Task GetGenesisContractAddressAsync() + { + var statusDto = await GetChainStatusAsync(); + var genesisAddress = statusDto?.GenesisContractAddress; + return genesisAddress; + } + + /// + /// Get address of a contract by given contractNameHash. + /// + /// + /// Address + public async Task
GetContractAddressByNameAsync(Hash contractNameHash) + { + var from = GetAddressFromPrivateKey(AElfClientConstants.DefaultPrivateKey); + var to = await GetGenesisContractAddressAsync(); + var transaction = await GenerateTransactionAsync(from, to, "GetContractAddressByName", contractNameHash); + var txWithSig = SignTransaction(AElfClientConstants.DefaultPrivateKey, transaction); + + var response = await ExecuteTransactionAsync(new ExecuteTransactionDto + { + RawTransaction = txWithSig.ToByteArray().ToHex() + }); + var byteArray = ByteArrayHelper.HexStringToByteArray(response); + var address = Address.Parser.ParseFrom(byteArray); + + return address; + } + + /// + /// Build a transaction from the input parameters. + /// + /// + /// + /// + /// + /// Transaction unsigned + public async Task GenerateTransactionAsync(string? from, string? to, + string methodName, IMessage input) + { + try + { + AssertValidAddress(to); + var chainStatus = await GetChainStatusAsync(); + var transaction = new Transaction + { + From = from.ToAddress(), + To = Address.FromBase58(to), + MethodName = methodName, + Params = input.ToByteString(), + RefBlockNumber = chainStatus.BestChainHeight, + RefBlockPrefix = ByteString.CopyFrom(Hash.LoadFromHex(chainStatus.BestChainHash).Value + .Take(4).ToArray()) + }; + + return transaction; + } + catch (Exception ex) + { + throw new AElfClientException($"Failed to generate transaction: {ex.Message}"); + } + } + + /// + /// Convert the Address to the displayed string:symbol_base58-string_base58-string-chain-id + /// + /// + /// + public async Task GetFormattedAddressAsync(Address address) + { + var tokenContractAddress = await GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); + var fromAddress = GetAddressFromPrivateKey(AElfClientConstants.DefaultPrivateKey); + var toAddress = tokenContractAddress.ToBase58(); + var methodName = "GetPrimaryTokenSymbol"; + var param = new Empty(); + + var transaction = await GenerateTransactionAsync(fromAddress, toAddress, methodName, param); + var txWithSign = SignTransaction(AElfClientConstants.DefaultPrivateKey, transaction); + + var result = await ExecuteTransactionAsync(new ExecuteTransactionDto + { + RawTransaction = txWithSign.ToByteArray().ToHex() + }); + + var symbol = StringValue.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(result)); + var chainIdString = (await GetChainStatusAsync())?.ChainId; + + return $"{symbol.Value}_{address.ToBase58()}_{chainIdString}"; + } + + /// + /// Sign a transaction using private key. + /// + /// + /// + /// Transaction signed + public Transaction SignTransaction(string? privateKeyHex, Transaction transaction) + { + var transactionData = transaction.GetHash().ToByteArray(); + + privateKeyHex ??= AElfClientConstants.DefaultPrivateKey; + + // Sign the hash + var privateKey = ByteArrayHelper.HexStringToByteArray(privateKeyHex); + var signature = CryptoHelper.SignWithPrivateKey(privateKey, transactionData); + transaction.Signature = ByteString.CopyFrom(signature); + + return transaction; + } + + /// + /// Get the account address through the public key. + /// + /// + /// Account + public string GetAddressFromPubKey(string pubKey) + { + var publicKey = ByteArrayHelper.HexStringToByteArray(pubKey); + var address = Address.FromPublicKey(publicKey); + return address.ToBase58(); + } + + /// + /// Get the account address through the private key. + /// + /// + /// + public string? GetAddressFromPrivateKey(string? privateKeyHex) + { + var address = Address.FromPublicKey(GetAElfKeyPair(privateKeyHex).PublicKey); + return address.ToBase58(); + } + + public Address GetBase58String(string base58String) + { + return Address.FromBase58(base58String); + } + + public KeyPairInfo GenerateKeyPairInfo() + { + var keyPair = CryptoHelper.GenerateKeyPair(); + var privateKey = keyPair.PrivateKey.ToHex(); + var publicKey = keyPair.PublicKey.ToHex(); + var address = GetAddressFromPrivateKey(privateKey); + + return new KeyPairInfo + { + PrivateKey = privateKey, + PublicKey = publicKey, + Address = address + }; + } + + #region private methods + + private ECKeyPair GetAElfKeyPair(string? privateKeyHex) + { + var privateKey = ByteArrayHelper.HexStringToByteArray(privateKeyHex); + var keyPair = CryptoHelper.FromPrivateKey(privateKey); + + return keyPair; + } + + private string GetRequestUrl(string baseUrl, string relativeUrl) + { + return new Uri(new Uri(baseUrl + (baseUrl.EndsWith("/") ? "" : "/")), relativeUrl).ToString(); + } + + private void AssertValidAddress(params string?[] addresses) + { + try + { + foreach (var address in addresses) + { + Address.FromBase58(address); + } + } + catch (Exception) + { + throw new AElfClientException(Error.Message[Error.InvalidAddress]); + } + } + + private void AssertValidHash(params string[] hashes) + { + try + { + foreach (var hash in hashes) + { + Hash.LoadFromHex(hash); + } + } + catch (Exception) + { + throw new AElfClientException(Error.Message[Error.InvalidBlockHash]); + } + } + + private void AssertValidTransactionId(params string[] transactionIds) + { + try + { + foreach (var transactionId in transactionIds) + { + Hash.LoadFromHex(transactionId); + } + } + catch (Exception) + { + throw new AElfClientException(Error.Message[Error.InvalidTransactionId]); + } + } + + #endregion +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClient.Net.cs b/src/AElf.Client/AElfClient.Net.cs new file mode 100644 index 0000000..89b2f5b --- /dev/null +++ b/src/AElf.Client/AElfClient.Net.cs @@ -0,0 +1,80 @@ +using System.Net.Http.Headers; +using System.Text; +using AElf.Client.Dto; +using AElf.Client.Helper; +using AElf.Client.Services; + +namespace AElf.Client; + +public partial class AElfClient : INetAppService +{ + /// + /// Attempt to add a node to the connected network nodes.Input parameter contains the ipAddress of the node. + /// + /// + /// + /// + /// Add successfully or not + public async Task AddPeerAsync(string ipAddress, string userName, string password) + { + if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) + { + return false; + } + + var url = GetRequestUrl(_baseUrl, "api/net/peer"); + var parameters = new Dictionary + { + {"address", endpoint?.ToString() ?? AElfClientConstants.LocalEndpoint} + }; + + return await _httpService.PostResponseAsync(url, parameters, + authenticationHeaderValue: GetAuthenticationHeaderValue()); + } + + /// + /// Attempt to remove a node from the connected network nodes by given the ipAddress. + /// + /// + /// + /// + /// Delete successfully or not + public async Task RemovePeerAsync(string ipAddress, string userName, string password) + { + if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) + { + return false; + } + + var url = GetRequestUrl(_baseUrl, $"api/net/peer?address={endpoint}"); + return await _httpService.DeleteResponseAsObjectAsync(url, + authenticationHeaderValue: GetAuthenticationHeaderValue()); + } + + /// + /// Gets information about the peer nodes of the current node.Optional whether to include metrics. + /// + /// + /// Information about the peer nodes + public async Task?> GetPeersAsync(bool withMetrics) + { + var url = GetRequestUrl(_baseUrl, $"api/net/peers?withMetrics={withMetrics}"); + return await _httpService.GetResponseAsync>(url); + } + + /// + /// Get the node's network information. + /// + /// Network information + public async Task GetNetworkInfoAsync() + { + var url = GetRequestUrl(_baseUrl, "api/net/networkInfo"); + return await _httpService.GetResponseAsync(url); + } + + private AuthenticationHeaderValue GetAuthenticationHeaderValue() + { + var byteArray = Encoding.ASCII.GetBytes($"{_userName}:{_password}"); + return new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); + } +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClient.Transaction.cs b/src/AElf.Client/AElfClient.Transaction.cs new file mode 100644 index 0000000..d1b6b4a --- /dev/null +++ b/src/AElf.Client/AElfClient.Transaction.cs @@ -0,0 +1,165 @@ +using AElf.Client.Dto; +using AElf.Client.Services; + +namespace AElf.Client; + +public partial class AElfClient : ITransactionAppService +{ + /// + /// Get information about the current transaction pool. + /// + /// TransactionPoolStatusOutput + public async Task GetTransactionPoolStatusAsync() + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/transactionPoolStatus"); + return await _httpService.GetResponseAsync(url); + } + + /// + /// Call a read-only method of a contract. + /// + /// + /// + public async Task ExecuteTransactionAsync(ExecuteTransactionDto input) + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/executeTransaction"); + var parameters = new Dictionary + { + {"RawTransaction", input.RawTransaction} + }; + + var result = await _httpService.PostResponseAsync(url, parameters); + + if (result == null) + { + throw new AElfClientException("Failed to execute tx."); + } + + return result; + } + + /// + /// Call a method of a contract by given serialized strings. + /// + /// + /// Serialized result + public async Task ExecuteRawTransactionAsync(ExecuteRawTransactionDto input) + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/executeRawTransaction"); + var parameters = new Dictionary + { + {"RawTransaction", input.RawTransaction}, + {"Signature", input.Signature} + }; + + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Creates an unsigned serialized transaction. + /// + /// + /// CreateRawTransactionOutput + public async Task CreateRawTransactionAsync(CreateRawTransactionInput input) + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/rawTransaction"); + var parameters = new Dictionary + { + {"From", input.From}, + {"To", input.To}, + {"RefBlockNumber", input.RefBlockNumber.ToString()}, + {"RefBlockHash", input.RefBlockHash}, + {"MethodName", input.MethodName}, + {"Params", input.Params} + }; + + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Broadcast a serialized transaction. + /// + /// + /// SendRawTransactionOutput + public async Task SendRawTransactionAsync(SendRawTransactionInput input) + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/sendRawTransaction"); + var parameters = new Dictionary + { + {"Transaction", input.Transaction}, + {"Signature", input.Signature}, + {"ReturnTransaction", input.ReturnTransaction ? "true" : "false"} + }; + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Broadcast a transaction. + /// + /// + /// TransactionId + public async Task SendTransactionAsync(SendTransactionInput input) + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/sendTransaction"); + var parameters = new Dictionary + { + {"RawTransaction", input.RawTransaction} + }; + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Broadcast volume transactions. + /// + /// + /// TransactionIds + public async Task SendTransactionsAsync(SendTransactionsInput input) + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/sendTransactions"); + var parameters = new Dictionary + { + {"RawTransactions", input.RawTransactions} + }; + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Gets the result of transaction execution by the given transactionId. + /// + /// + /// TransactionResultDto + public async Task GetTransactionResultAsync(string transactionId) + { + AssertValidTransactionId(transactionId); + var url = GetRequestUrl(_baseUrl, $"api/blockChain/transactionResult?transactionId={transactionId}"); + return await _httpService.GetResponseAsync(url); + } + + /// + /// Get results of multiple transactions by specified blockHash and the offset. + /// + /// + /// + /// + /// TransactionResultDtos + public async Task?> GetTransactionResultsAsync(string blockHash, int offset = 0, + int limit = 10) + { + AssertValidHash(blockHash); + var url = GetRequestUrl(_baseUrl, + $"api/blockChain/transactionResults?blockHash={blockHash}&offset={offset}&limit={limit}"); + return await _httpService.GetResponseAsync>(url); + } + + /// + /// Get merkle path of a transaction. + /// + /// + /// MerklePathDto + public async Task GetMerklePathByTransactionIdAsync(string transactionId) + { + AssertValidTransactionId(transactionId); + var url = GetRequestUrl(_baseUrl, $"api/blockChain/merklePathByTransactionId?transactionId={transactionId}"); + return await _httpService.GetResponseAsync(url); + } +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClient.cs b/src/AElf.Client/AElfClient.cs new file mode 100644 index 0000000..a45bb29 --- /dev/null +++ b/src/AElf.Client/AElfClient.cs @@ -0,0 +1,38 @@ +using System.Text.Json; +using AElf.Client.Service; + +namespace AElf.Client; + +public partial class AElfClient : IDisposable +{ + private readonly IHttpService _httpService; + private readonly string _baseUrl; + private readonly string _userName; + private readonly string _password; + + public AElfClient(string baseUrl, int timeOut = 60, string userName = null, string password = null) + { + _httpService = new HttpService(timeOut); + _baseUrl = baseUrl; + _userName = userName; + _password = password; + } + + private bool _disposed; + + /// + public void Dispose() + { + if (_disposed) return; + Dispose(true); + _disposed = true; + } + + /// + /// Disposes the resources associated with the object. + /// + /// true if called by a call to the Dispose method; otherwise false. + protected virtual void Dispose(bool disposing) + { + } +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClientBuilder.cs b/src/AElf.Client/AElfClientBuilder.cs new file mode 100644 index 0000000..c2a04fe --- /dev/null +++ b/src/AElf.Client/AElfClientBuilder.cs @@ -0,0 +1,65 @@ +namespace AElf.Client; + +public sealed class AElfClientBuilder +{ + private string NodeEndpoint { get; set; } + private int Timeout { get; set; } + + private string UserName { get; set; } + private string Password { get; set; } + + public AElfClientBuilder() + { + NodeEndpoint = AElfClientConstants.LocalEndpoint; + Timeout = 60; + } + + public AElfClientBuilder UseEndpoint(string endpoint) + { + NodeEndpoint = endpoint; + return this; + } + + public AElfClientBuilder UsePublicEndpoint(EndpointType endpointType) + { + switch (endpointType) + { + case EndpointType.MainNetMainChain: + NodeEndpoint = AElfClientConstants.MainNetMainChain; + break; + case EndpointType.MainNetSidechain: + NodeEndpoint = AElfClientConstants.MainNetSidechain; + break; + case EndpointType.TestNetMainChain: + NodeEndpoint = AElfClientConstants.TestNetMainChain; + break; + case EndpointType.TestNetSidechain: + NodeEndpoint = AElfClientConstants.TestNetSidechain; + break; + case EndpointType.Local: + default: + NodeEndpoint = AElfClientConstants.LocalEndpoint; + break; + } + + return this; + } + + public AElfClientBuilder SetHttpTimeout(int timeout) + { + Timeout = timeout; + return this; + } + + public AElfClientBuilder ManagePeerInfo(string userName, string password) + { + UserName = userName; + Password = password; + return this; + } + + public AElfClient Build() + { + return new AElfClient(NodeEndpoint, Timeout, UserName, Password); + } +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClientConstants.cs b/src/AElf.Client/AElfClientConstants.cs new file mode 100644 index 0000000..6c1efc9 --- /dev/null +++ b/src/AElf.Client/AElfClientConstants.cs @@ -0,0 +1,13 @@ +namespace AElf.Client; + +public class AElfClientConstants +{ + public const string DefaultPrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; + public const string LocalEndpoint = "http://127.0.0.1:1235"; + public const string MainNetMainChain = "https://aelf-public-node.aelf.io"; + public const string MainNetSidechain = "https://tdvv-public-node.aelf.io"; + public const string TestNetMainChain = "https://aelf-test-node.aelf.io"; + public const string TestNetSidechain = "https://tdvv-test-node.aelf.io"; + public const int MainChainId = 9992731; + public const int SidechainId = 9992731; +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClientModule.cs b/src/AElf.Client/AElfClientModule.cs new file mode 100644 index 0000000..c300af4 --- /dev/null +++ b/src/AElf.Client/AElfClientModule.cs @@ -0,0 +1,17 @@ +using AElf.Client.Options; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace AElf.Client; + +[DependsOn( + typeof(AbpAutofacModule) + )] +public class AElfClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(context.Services.GetConfiguration().GetSection("AElfClient")); + } +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClientService.cs b/src/AElf.Client/AElfClientService.cs new file mode 100644 index 0000000..06cd2f5 --- /dev/null +++ b/src/AElf.Client/AElfClientService.cs @@ -0,0 +1,21 @@ +using AElf.Client.Options; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace AElf.Client; + +public class AElfClientService : IAElfClientService, ITransientDependency +{ + private readonly IAElfClientProvider _aelfClientProvider; + private readonly AElfClientOptions _aelfClientOptions; + private readonly AElfAccountOptions _aelfAccountOptions; + + public AElfClientService(IAElfClientProvider aelfClientProvider, IOptionsSnapshot aelfClientOptions, + IOptionsSnapshot aelfAccountOptions) + { + _aelfClientProvider = aelfClientProvider; + _aelfClientOptions = aelfClientOptions.Value; + _aelfAccountOptions = aelfAccountOptions.Value; + + } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/BlockBodyDto.cs b/src/AElf.Client/Dto/BlockBodyDto.cs new file mode 100644 index 0000000..e2832e3 --- /dev/null +++ b/src/AElf.Client/Dto/BlockBodyDto.cs @@ -0,0 +1,8 @@ +namespace AElf.Client.Dto; + +public class BlockBodyDto +{ + public int TransactionsCount { get; set; } + + public List Transactions { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/BlockDto.cs b/src/AElf.Client/Dto/BlockDto.cs new file mode 100644 index 0000000..2c25367 --- /dev/null +++ b/src/AElf.Client/Dto/BlockDto.cs @@ -0,0 +1,10 @@ +namespace AElf.Client.Dto; + +public class BlockDto +{ + public string BlockHash { get; set; } + + public BlockHeaderDto Header { get; set; } + + public BlockBodyDto Body { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/BlockHeaderDto.cs b/src/AElf.Client/Dto/BlockHeaderDto.cs new file mode 100644 index 0000000..699ff94 --- /dev/null +++ b/src/AElf.Client/Dto/BlockHeaderDto.cs @@ -0,0 +1,24 @@ +namespace AElf.Client.Dto; + +public class BlockHeaderDto +{ + public string PreviousBlockHash { get; set; } + + public string MerkleTreeRootOfTransactions { get; set; } + + public string MerkleTreeRootOfWorldState { get; set; } + + public string MerkleTreeRootOfTransactionState { get; set; } + + public string Extra { get; set; } + + public long Height { get; set; } + + public DateTime Time { get; set; } + + public string ChainId { get; set; } + + public string Bloom { get; set; } + + public string SignerPubkey { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/ChainStatusDto.cs b/src/AElf.Client/Dto/ChainStatusDto.cs new file mode 100644 index 0000000..2cb6580 --- /dev/null +++ b/src/AElf.Client/Dto/ChainStatusDto.cs @@ -0,0 +1,26 @@ +namespace AElf.Client.Dto; + +public class ChainStatusDto +{ + public string ChainId { get; set; } + + public Dictionary Branches { get; set; } + + public Dictionary NotLinkedBlocks { get; set; } + + public long LongestChainHeight { get; set; } + + public string LongestChainHash { get; set; } + + public string GenesisBlockHash { get; set; } + + public string GenesisContractAddress { get; set; } + + public string LastIrreversibleBlockHash { get; set; } + + public long LastIrreversibleBlockHeight { get; set; } + + public string BestChainHash { get; set; } + + public long BestChainHeight { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/CreateRawTransactionInput.cs b/src/AElf.Client/Dto/CreateRawTransactionInput.cs new file mode 100644 index 0000000..ee21c92 --- /dev/null +++ b/src/AElf.Client/Dto/CreateRawTransactionInput.cs @@ -0,0 +1,78 @@ +using System.ComponentModel.DataAnnotations; + +namespace AElf.Client.Dto; + +public class CreateRawTransactionInput : IValidatableObject +{ + /// + /// from address + /// + [Required] + public string From { get; set; } + + /// + /// to address + /// + [Required] + public string To { get; set; } + + /// + /// refer block height + /// + [Required] + public long RefBlockNumber { get; set; } + + /// + /// refer block hash + /// + [Required] + public string RefBlockHash { get; set; } + + /// + /// contract method name + /// + [Required] + public string MethodName { get; set; } + + /// + /// contract method parameters + /// + [Required] + public string Params { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) + { + var validationResults = new List(); + try + { + Address.FromBase58(From); + } + catch + { + validationResults.Add(new ValidationResult(Error.Message[Error.InvalidAddress], + new[] {nameof(From)})); + } + + try + { + Address.FromBase58(To); + } + catch + { + validationResults.Add( + new ValidationResult(Error.Message[Error.InvalidAddress], new[] {nameof(To)})); + } + + try + { + Hash.LoadFromHex(RefBlockHash); + } + catch + { + validationResults.Add( + new ValidationResult(Error.Message[Error.InvalidBlockHash], new[] {nameof(RefBlockHash)})); + } + + return validationResults; + } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/CreateRawTransactionOutput.cs b/src/AElf.Client/Dto/CreateRawTransactionOutput.cs new file mode 100644 index 0000000..7896ec8 --- /dev/null +++ b/src/AElf.Client/Dto/CreateRawTransactionOutput.cs @@ -0,0 +1,6 @@ +namespace AElf.Client.Dto; + +public class CreateRawTransactionOutput +{ + public string RawTransaction { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs b/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs new file mode 100644 index 0000000..b07cd89 --- /dev/null +++ b/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs @@ -0,0 +1,14 @@ +namespace AElf.Client.Dto; + +public class ExecuteRawTransactionDto +{ + /// + /// raw transaction + /// + public string RawTransaction { get; set; } + + /// + /// signature + /// + public string Signature { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/ExecuteTransactionDto.cs b/src/AElf.Client/Dto/ExecuteTransactionDto.cs new file mode 100644 index 0000000..5ee6279 --- /dev/null +++ b/src/AElf.Client/Dto/ExecuteTransactionDto.cs @@ -0,0 +1,9 @@ +namespace AElf.Client.Dto; + +public class ExecuteTransactionDto +{ + /// + /// raw transaction + /// + public string RawTransaction { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/LogEventDto.cs b/src/AElf.Client/Dto/LogEventDto.cs new file mode 100644 index 0000000..74dfd09 --- /dev/null +++ b/src/AElf.Client/Dto/LogEventDto.cs @@ -0,0 +1,12 @@ +namespace AElf.Client.Dto; + +public class LogEventDto +{ + public string Address { get; set; } + + public string Name { get; set; } + + public string[] Indexed { get; set; } + + public string NonIndexed { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/MerklePathDto.cs b/src/AElf.Client/Dto/MerklePathDto.cs new file mode 100644 index 0000000..ee0f9d1 --- /dev/null +++ b/src/AElf.Client/Dto/MerklePathDto.cs @@ -0,0 +1,12 @@ +namespace AElf.Client.Dto; + +public class MerklePathDto +{ + public List MerklePathNodes; +} + +public class MerklePathNodeDto +{ + public string Hash { get; set; } + public bool IsLeftChildNode { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/NetworkInfoOutput.cs b/src/AElf.Client/Dto/NetworkInfoOutput.cs new file mode 100644 index 0000000..50f76a5 --- /dev/null +++ b/src/AElf.Client/Dto/NetworkInfoOutput.cs @@ -0,0 +1,19 @@ +namespace AElf.Client.Dto; + +public class NetworkInfoOutput +{ + /// + /// node version + /// + public string Version { get; set; } + + /// + /// network protocol version + /// + public int ProtocolVersion { get; set; } + + /// + /// total number of open connections between this node and other nodes + /// + public int Connections { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/PeerDto.cs b/src/AElf.Client/Dto/PeerDto.cs new file mode 100644 index 0000000..411c2df --- /dev/null +++ b/src/AElf.Client/Dto/PeerDto.cs @@ -0,0 +1,22 @@ +namespace AElf.Client.Dto; + +public class PeerDto +{ + public string IpAddress { get; set; } + public int ProtocolVersion { get; set; } + public long ConnectionTime { get; set; } + public string ConnectionStatus { get; set; } + public bool Inbound { get; set; } + public int BufferedTransactionsCount { get; set; } + public int BufferedBlocksCount { get; set; } + public int BufferedAnnouncementsCount { get; set; } + public List RequestMetrics { get; set; } +} + +public class RequestMetric +{ + public long RoundTripTime { get; set; } + public string MethodName { get; set; } + public string Info { get; set; } + public string RequestTime { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/SendRawTransactionInput.cs b/src/AElf.Client/Dto/SendRawTransactionInput.cs new file mode 100644 index 0000000..e5941ec --- /dev/null +++ b/src/AElf.Client/Dto/SendRawTransactionInput.cs @@ -0,0 +1,19 @@ +namespace AElf.Client.Dto; + +public class SendRawTransactionInput +{ + /// + /// raw transaction + /// + public string Transaction { get; set; } + + /// + /// signature + /// + public string Signature { get; set; } + + /// + /// return transaction detail or not + /// + public bool ReturnTransaction { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/SendRawTransactionOutput.cs b/src/AElf.Client/Dto/SendRawTransactionOutput.cs new file mode 100644 index 0000000..25046c8 --- /dev/null +++ b/src/AElf.Client/Dto/SendRawTransactionOutput.cs @@ -0,0 +1,8 @@ +namespace AElf.Client.Dto; + +public class SendRawTransactionOutput +{ + public string TransactionId { get; set; } + + public TransactionDto Transaction { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/SendTransactionInput.cs b/src/AElf.Client/Dto/SendTransactionInput.cs new file mode 100644 index 0000000..1e1c8cc --- /dev/null +++ b/src/AElf.Client/Dto/SendTransactionInput.cs @@ -0,0 +1,9 @@ +namespace AElf.Client.Dto; + +public class SendTransactionInput +{ + /// + /// raw transaction + /// + public string RawTransaction { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/SendTransactionOutput.cs b/src/AElf.Client/Dto/SendTransactionOutput.cs new file mode 100644 index 0000000..f22ca67 --- /dev/null +++ b/src/AElf.Client/Dto/SendTransactionOutput.cs @@ -0,0 +1,6 @@ +namespace AElf.Client.Dto; + +public class SendTransactionOutput +{ + public string TransactionId { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/SendTransactionsInput.cs b/src/AElf.Client/Dto/SendTransactionsInput.cs new file mode 100644 index 0000000..c623c74 --- /dev/null +++ b/src/AElf.Client/Dto/SendTransactionsInput.cs @@ -0,0 +1,9 @@ +namespace AElf.Client.Dto; + +public class SendTransactionsInput +{ + /// + /// raw transactions + /// + public string RawTransactions { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/TaskQueueInfoDto.cs b/src/AElf.Client/Dto/TaskQueueInfoDto.cs new file mode 100644 index 0000000..d02fc56 --- /dev/null +++ b/src/AElf.Client/Dto/TaskQueueInfoDto.cs @@ -0,0 +1,8 @@ +namespace AElf.Client.Dto; + +public class TaskQueueInfoDto +{ + public string Name { get; set; } + + public int Size { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/TransactionDto.cs b/src/AElf.Client/Dto/TransactionDto.cs new file mode 100644 index 0000000..fbfc40d --- /dev/null +++ b/src/AElf.Client/Dto/TransactionDto.cs @@ -0,0 +1,18 @@ +namespace AElf.Client.Dto; + +public class TransactionDto +{ + public string From { get; set; } + + public string To { get; set; } + + public long RefBlockNumber { get; set; } + + public string RefBlockPrefix { get; set; } + + public string MethodName { get; set; } + + public string Params { get; set; } + + public string Signature { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs b/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs new file mode 100644 index 0000000..ba60b96 --- /dev/null +++ b/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs @@ -0,0 +1,7 @@ +namespace AElf.Client.Dto; + +public class TransactionPoolStatusOutput +{ + public int Queued { get; set; } + public int Validated { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/TransactionResultDto.cs b/src/AElf.Client/Dto/TransactionResultDto.cs new file mode 100644 index 0000000..30ff3fa --- /dev/null +++ b/src/AElf.Client/Dto/TransactionResultDto.cs @@ -0,0 +1,22 @@ +namespace AElf.Client.Dto; + +public class TransactionResultDto +{ + public string TransactionId { get; set; } + + public string Status { get; set; } + + public LogEventDto[] Logs { get; set; } + + public string Bloom { get; set; } + + public long BlockNumber { get; set; } + + public string BlockHash { get; set; } + + public TransactionDto Transaction { get; set; } + + public string ReturnValue { get; set; } + + public string Error { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/EndpointType.cs b/src/AElf.Client/EndpointType.cs new file mode 100644 index 0000000..0b132fa --- /dev/null +++ b/src/AElf.Client/EndpointType.cs @@ -0,0 +1,10 @@ +namespace AElf.Client; + +public enum EndpointType +{ + MainNetMainChain, + MainNetSidechain, + TestNetMainChain, + TestNetSidechain, + Local +} \ No newline at end of file diff --git a/src/AElf.Client/Exception/AElfClientException.cs b/src/AElf.Client/Exception/AElfClientException.cs new file mode 100644 index 0000000..1f9c409 --- /dev/null +++ b/src/AElf.Client/Exception/AElfClientException.cs @@ -0,0 +1,9 @@ +namespace AElf.Client; + +public class AElfClientException : Exception +{ + public AElfClientException(string message) : base(message) + { + + } +} \ No newline at end of file diff --git a/src/AElf.Client/Exception/Error.cs b/src/AElf.Client/Exception/Error.cs new file mode 100644 index 0000000..fc78fc6 --- /dev/null +++ b/src/AElf.Client/Exception/Error.cs @@ -0,0 +1,35 @@ +namespace AElf.Client; + +public class Error +{ + public const int NotFound = 20001; + public const int InvalidAddress = 20002; + public const int InvalidBlockHash = 20003; + public const int InvalidTransactionId = 20004; + public const int InvalidProposalId = 20005; + public const int InvalidOffset = 20006; + public const int InvalidLimit = 20007; + public const int InvalidTransaction = 20008; + public const int CannotBroadcastTransaction = 20009; + public const int InvalidContractAddress = 20010; + public const int NoMatchMethodInContractAddress = 20011; + public const int InvalidParams = 20012; + public const int InvalidSignature = 20013; + + public static readonly Dictionary Message = new Dictionary + { + {NotFound, "Not found"}, + {InvalidAddress, "Invalid address format"}, + {InvalidBlockHash, "Invalid block hash format"}, + {InvalidTransactionId, "Invalid Transaction id format"}, + {InvalidProposalId, "Invalid proposal id format"}, + {InvalidOffset, "Offset must greater than or equal to 0"}, + {InvalidLimit, "Limit must between 0 and 100"}, + {InvalidTransaction, "Invalid transaction information"}, + {CannotBroadcastTransaction, "Sync still in progress, cannot send transactions"}, + {InvalidContractAddress, "Invalid contract address"}, + {NoMatchMethodInContractAddress, "No match method in contract address"}, + {InvalidParams, "Invalid params"}, + {InvalidSignature, "Invalid signature"} + }; +} \ No newline at end of file diff --git a/src/AElf.Client/Extensions/StringExtensions.cs b/src/AElf.Client/Extensions/StringExtensions.cs new file mode 100644 index 0000000..7b2108f --- /dev/null +++ b/src/AElf.Client/Extensions/StringExtensions.cs @@ -0,0 +1,14 @@ +namespace AElf.Client.Extensions; + +public static class StringExtensions +{ + public static Address ToAddress(this string? address) + { + if (address == null) + { + return Address.FromPublicKey(ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey)); + } + + return Address.FromBase58(address); + } +} \ No newline at end of file diff --git a/src/AElf.Client/GlobalUsings.cs b/src/AElf.Client/GlobalUsings.cs new file mode 100644 index 0000000..e2e7f5c --- /dev/null +++ b/src/AElf.Client/GlobalUsings.cs @@ -0,0 +1 @@ +global using AElf.Types; \ No newline at end of file diff --git a/src/AElf.Client/Helper/EndpointHelper.cs b/src/AElf.Client/Helper/EndpointHelper.cs new file mode 100644 index 0000000..3d04103 --- /dev/null +++ b/src/AElf.Client/Helper/EndpointHelper.cs @@ -0,0 +1,95 @@ +using System.Linq; +using System.Net; +using System.Net.Sockets; + +namespace AElf.Client.Helper +{ + public static class EndpointHelper + { + public static bool TryParse(string endpointString, out DnsEndPoint? endpoint, + int defaultPort = 6800) + { + endpoint = null; + + if (string.IsNullOrEmpty(endpointString) || endpointString.Trim().Length == 0) + return false; + + if (defaultPort != -1 && (defaultPort < IPEndPoint.MinPort || defaultPort > IPEndPoint.MaxPort)) + return false; + + var values = endpointString.Split(new[] {':'}); + string host; + var port = -1; + + switch (values.Length) + { + case <= 2: + { + // ipv4 or hostname + host = values[0]; + + if (values.Length == 1) + { + port = defaultPort; + } + else + { + var parsedPort = GetPort(values[1]); + + if (parsedPort == 0) + return false; + + port = parsedPort; + } + + break; + } + //ipv6 + //could be [a:b:c]:d + case > 2 when values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]"): + { + host = string.Join(":", values.Take(values.Length - 1).ToArray()); + var parsedPort = GetPort(values[values.Length - 1]); + + if (parsedPort == 0) + return false; + break; + } + // [a:b:c] or a:b:c + case > 2: + host = endpointString; + port = defaultPort; + break; + } + + if (port == -1) + return false; + + // we leave semantic analysis of the ip/hostname to lower levels. + endpoint = new PeerEndpoint(host, port); + + return true; + } + + private static int GetPort(string p) + { + if (!int.TryParse(p, out int port) || port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort) + return 0; + + return port; + } + } + + public class PeerEndpoint : DnsEndPoint + { + public PeerEndpoint(string host, int port) + : base(host, port, AddressFamily.Unspecified) + { + } + + public override string ToString() + { + return Host + ":" + Port; + } + } +} \ No newline at end of file diff --git a/src/AElf.Client/IAElfClientProvider.cs b/src/AElf.Client/IAElfClientProvider.cs new file mode 100644 index 0000000..46e22cc --- /dev/null +++ b/src/AElf.Client/IAElfClientProvider.cs @@ -0,0 +1,66 @@ +using Volo.Abp.DependencyInjection; + +namespace AElf.Client; + +public interface IAElfClientProvider +{ + AElfClient GetClient(string? alias = null, string? environment = null, int? chainId = null, string? chainType = null); + + void SetClient(AElfClient client, string? environment = null, int? chainId = null, string? chainType = null, + string? alias = null); +} + +public class AElfClientProvider : Dictionary, IAElfClientProvider, ISingletonDependency +{ + public AElfClientProvider() + { + var clientBuilder = new AElfClientBuilder(); + SetClient(clientBuilder.UsePublicEndpoint(EndpointType.MainNetMainChain).Build(), "MainNet", + AElfClientConstants.MainChainId, "MainChain", EndpointType.MainNetMainChain.ToString()); + SetClient(clientBuilder.UsePublicEndpoint(EndpointType.MainNetSidechain).Build(), "MainNet", + AElfClientConstants.SidechainId, "Sidechain", EndpointType.MainNetSidechain.ToString()); + SetClient(clientBuilder.UsePublicEndpoint(EndpointType.TestNetMainChain).Build(), "TestNet", + AElfClientConstants.MainChainId, "MainChain", EndpointType.TestNetMainChain.ToString()); + SetClient(clientBuilder.UsePublicEndpoint(EndpointType.TestNetSidechain).Build(), "MainNet", + AElfClientConstants.SidechainId, "Sidechain", EndpointType.TestNetSidechain.ToString()); + SetClient(clientBuilder.UsePublicEndpoint(EndpointType.Local).Build(), "Local", AElfClientConstants.MainChainId, + "MainChain", EndpointType.Local.ToString()); + } + + public AElfClient GetClient(string? alias = null, string? environment = null, int? chainId = null, + string? chainType = null) + { + var keys = Keys + .WhereIf(!alias.IsNullOrWhiteSpace(), c => c.Alias == alias) + .WhereIf(!environment.IsNullOrWhiteSpace(), c => c.Environment == environment) + .WhereIf(chainId.HasValue, c => c.ChainId == chainId) + .WhereIf(!chainType.IsNullOrWhiteSpace(), c => c.ChainType == chainType) + .ToList(); + if (keys.Count != 1) + { + throw new AElfClientException($"Failed to get client of {alias} - {environment} - {chainId} - {chainType}"); + } + + return this[keys.Single()]; + } + + public void SetClient(AElfClient client, string? environment = null, int? chainId = null, string? chainType = null, + string? alias = null) + { + TryAdd(new AElfClientInfo + { + Environment = environment, + ChainId = chainId, + ChainType = chainType, + Alias = alias + }, client); + } +} + +public class AElfClientInfo +{ + public string? Environment { get; set; } + public int? ChainId { get; set; } + public string? ChainType { get; set; } + public string? Alias { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/IAElfClientService.cs b/src/AElf.Client/IAElfClientService.cs new file mode 100644 index 0000000..e92feb5 --- /dev/null +++ b/src/AElf.Client/IAElfClientService.cs @@ -0,0 +1,6 @@ +namespace AElf.Client; + +public interface IAElfClientService +{ + +} \ No newline at end of file diff --git a/src/AElf.Client/Model/KeyPairInfo.cs b/src/AElf.Client/Model/KeyPairInfo.cs new file mode 100644 index 0000000..cf9f189 --- /dev/null +++ b/src/AElf.Client/Model/KeyPairInfo.cs @@ -0,0 +1,9 @@ +namespace AElf.Client.Model +{ + public class KeyPairInfo + { + public string PrivateKey { get; set; } + public string PublicKey { get; set; } + public string? Address { get; set; } + } +} \ No newline at end of file diff --git a/src/AElf.Client/Options/AElfAccountOptions.cs b/src/AElf.Client/Options/AElfAccountOptions.cs new file mode 100644 index 0000000..dcc88fc --- /dev/null +++ b/src/AElf.Client/Options/AElfAccountOptions.cs @@ -0,0 +1,13 @@ +namespace AElf.Client.Options; + +public class AElfAccountOptions +{ + public string KeyDirectory { get; set; } + public Dictionary AccountConfigs { get; set; } +} + +public class AccountConfig +{ + public string Password { get; set; } + public string PrivateKey { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Options/AElfClientOptions.cs b/src/AElf.Client/Options/AElfClientOptions.cs new file mode 100644 index 0000000..375ec6f --- /dev/null +++ b/src/AElf.Client/Options/AElfClientOptions.cs @@ -0,0 +1,14 @@ +namespace AElf.Client.Options; + +public class AElfClientOptions +{ + public Dictionary ClientConfigs { get; set; } +} + +public class ClientConfig +{ + public string Endpoint { get; set; } + public string UserName { get; set; } + public string Password { get; set; } + public int Timeout { get; set; } = 60; +} \ No newline at end of file diff --git a/src/AElf.Client/Services/HttpService.cs b/src/AElf.Client/Services/HttpService.cs new file mode 100644 index 0000000..74bbdde --- /dev/null +++ b/src/AElf.Client/Services/HttpService.cs @@ -0,0 +1,215 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace AElf.Client.Service; + +public interface IHttpService +{ + Task GetResponseAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK); + + Task PostResponseAsync(string url, Dictionary parameters, + string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue? authenticationHeaderValue = null); + + Task DeleteResponseAsObjectAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null); +} + +public class HttpService : IHttpService +{ + private HttpClient Client { get; set; } + private int TimeoutSeconds { get; } + + public HttpService(int timeoutSeconds) + { + TimeoutSeconds = timeoutSeconds; + } + + /// + /// Get request. + /// + /// + /// + /// + /// + /// + public async Task GetResponseAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + var response = await GetResponseAsync(url, version, expectedStatusCode); + var stream = await response.Content.ReadAsStreamAsync(); + return await JsonSerializer.DeserializeAsync(stream); + } + + /// + /// Post request. + /// + /// + /// + /// + /// + /// + /// + /// + public async Task PostResponseAsync(string url, Dictionary parameters, + string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue? authenticationHeaderValue = null) + { + var response = await PostResponseAsync(url, parameters, version, true, expectedStatusCode, + authenticationHeaderValue); + var stream = await response.Content.ReadAsStreamAsync(); + return await JsonSerializer.DeserializeAsync(stream); + } + + /// + /// Delete request. + /// + /// + /// + /// + /// + /// + /// + public async Task DeleteResponseAsObjectAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) + { + var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); + var stream = await response.Content.ReadAsStreamAsync(); + return await JsonSerializer.DeserializeAsync(stream); + } + + #region GetResponse + + private async Task GetResponseAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + { + version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; + + var client = GetHttpClient(version); + try + { + var response = await client.GetAsync(url); + if (response.StatusCode == expectedStatusCode) + return response; + throw new AElfClientException(response.ToString()); + } + catch (Exception ex) + { + throw new AElfClientException(ex.Message); + } + } + + #endregion + + #region PostResponse + + private async Task PostResponseAsync(string url, + Dictionary parameters, + string? version = null, bool useApplicationJson = false, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue? authenticationHeaderValue = null) + { + version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; + var client = GetHttpClient(version); + + if (authenticationHeaderValue != null) + { + client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; + } + + HttpContent content; + if (useApplicationJson) + { + var paramsStr = JsonSerializer.Serialize(parameters); + content = new StringContent(paramsStr, Encoding.UTF8, "application/json"); + content.Headers.ContentType = MediaTypeHeaderValue.Parse($"application/json{version}"); + } + + else + { + content = new FormUrlEncodedContent(parameters); + content.Headers.ContentType = + MediaTypeHeaderValue.Parse($"application/x-www-form-urlencoded{version}"); + } + + try + { + var response = await client.PostAsync(url, content); + if (response.StatusCode == expectedStatusCode) + return response; + var message = await response.Content.ReadAsStringAsync(); + throw new HttpRequestException(message); + } + catch (Exception ex) + { + throw new AElfClientException(ex.Message); + } + } + + #endregion + + #region DeleteResponse + + private async Task DeleteResponseAsStringAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) + { + var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); + return await response.Content.ReadAsStringAsync(); + } + + private async Task DeleteResponseAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) + { + version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; + var client = GetHttpClient(version); + + if (authenticationHeaderValue != null) + { + client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; + } + + try + { + var response = await client.DeleteAsync(url); + if (response.StatusCode == expectedStatusCode) + return response; + throw new AElfClientException(response.ToString()); + } + catch (Exception ex) + { + throw new AElfClientException(ex.Message); + } + } + + #endregion + + #region private methods + + private HttpClient GetHttpClient(string? version = null) + { + if (Client != null) return Client; + Client = new HttpClient + { + Timeout = TimeSpan.FromSeconds(TimeoutSeconds) + }; + Client.DefaultRequestHeaders.Accept.Clear(); + Client.DefaultRequestHeaders.Accept.Add( + MediaTypeWithQualityHeaderValue.Parse($"application/json{version}")); + Client.DefaultRequestHeaders.Add("Connection", "close"); + return Client; + } + + #endregion +} \ No newline at end of file diff --git a/src/AElf.Client/Services/IBlockAppService.cs b/src/AElf.Client/Services/IBlockAppService.cs new file mode 100644 index 0000000..ec449cf --- /dev/null +++ b/src/AElf.Client/Services/IBlockAppService.cs @@ -0,0 +1,12 @@ +using AElf.Client.Dto; + +namespace AElf.Client.Services; + +public interface IBlockAppService +{ + Task GetBlockHeightAsync(); + + Task GetBlockByHashAsync(string blockHash, bool includeTransactions = false); + + Task GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false); +} \ No newline at end of file diff --git a/src/AElf.Client/Services/IChainAppService.cs b/src/AElf.Client/Services/IChainAppService.cs new file mode 100644 index 0000000..48d9b61 --- /dev/null +++ b/src/AElf.Client/Services/IChainAppService.cs @@ -0,0 +1,15 @@ +using AElf.Client.Dto; +using AElf.Kernel; + +namespace AElf.Client; + +public interface IChainAppService +{ + Task GetChainStatusAsync(); + + Task GetContractFileDescriptorSetAsync(string? address); + + Task> GetTaskQueueStatusAsync(); + + Task GetChainIdAsync(); +} \ No newline at end of file diff --git a/src/AElf.Client/Services/IClientService.cs b/src/AElf.Client/Services/IClientService.cs new file mode 100644 index 0000000..8331a7a --- /dev/null +++ b/src/AElf.Client/Services/IClientService.cs @@ -0,0 +1,13 @@ +using AElf.Client.Model; + +namespace AElf.Client.Services; + +public interface IClientService +{ + Task IsConnectedAsync(); + Task GetFormattedAddressAsync(Address address); + Task GetGenesisContractAddressAsync(); + Task
GetContractAddressByNameAsync(Hash contractNameHash); + string GetAddressFromPubKey(string pubKey); + KeyPairInfo GenerateKeyPairInfo(); +} \ No newline at end of file diff --git a/src/AElf.Client/Services/INetAppService.cs b/src/AElf.Client/Services/INetAppService.cs new file mode 100644 index 0000000..ada9aea --- /dev/null +++ b/src/AElf.Client/Services/INetAppService.cs @@ -0,0 +1,14 @@ +using AElf.Client.Dto; + +namespace AElf.Client.Services; + +public interface INetAppService +{ + Task AddPeerAsync(string ipAddress, string userName, string password); + + Task RemovePeerAsync(string ipAddress, string userName, string password); + + Task?> GetPeersAsync(bool withMetrics); + + Task GetNetworkInfoAsync(); +} \ No newline at end of file diff --git a/src/AElf.Client/Services/ITransactionAppService.cs b/src/AElf.Client/Services/ITransactionAppService.cs new file mode 100644 index 0000000..2bf140a --- /dev/null +++ b/src/AElf.Client/Services/ITransactionAppService.cs @@ -0,0 +1,27 @@ +using AElf.Client.Dto; + +namespace AElf.Client.Services; + +public interface ITransactionAppService +{ + Task GetTransactionPoolStatusAsync(); + + Task ExecuteTransactionAsync(ExecuteTransactionDto input); + + Task ExecuteRawTransactionAsync(ExecuteRawTransactionDto input); + + Task CreateRawTransactionAsync(CreateRawTransactionInput input); + + Task SendRawTransactionAsync(SendRawTransactionInput input); + + Task SendTransactionAsync(SendTransactionInput input); + + Task SendTransactionsAsync(SendTransactionsInput input); + + Task GetTransactionResultAsync(string transactionId); + + Task?> GetTransactionResultsAsync(string blockHash, int offset = 0, + int limit = 10); + + Task GetMerklePathByTransactionIdAsync(string transactionId); +} \ No newline at end of file diff --git a/src/AElf.Client/TransactionBuilder.cs b/src/AElf.Client/TransactionBuilder.cs new file mode 100644 index 0000000..0bfdb0c --- /dev/null +++ b/src/AElf.Client/TransactionBuilder.cs @@ -0,0 +1,60 @@ +using AElf.Cryptography; +using Google.Protobuf; + +namespace AElf.Client; + +public class TransactionBuilder +{ + private readonly AElfClient _aelfClient; + + private string PrivateKey { get; set; } + private string ContractAddress { get; set; } + private string MethodName { get; set; } + private IMessage Parameter { get; set; } + + public TransactionBuilder(AElfClient aelfClient) + { + _aelfClient = aelfClient; + PrivateKey = AElfClientConstants.DefaultPrivateKey; + } + + public TransactionBuilder UsePrivateKey(string privateKey) + { + PrivateKey = privateKey; + return this; + } + + public TransactionBuilder UseSystemContract(string systemContractName) + { + ContractAddress = _aelfClient.GetContractAddressByNameAsync(HashHelper.ComputeFrom(systemContractName)) + .Result.ToBase58(); + return this; + } + + public TransactionBuilder UseContract(string contractAddress) + { + ContractAddress = contractAddress; + return this; + } + + public TransactionBuilder UseMethod(string methodName) + { + MethodName = methodName; + return this; + } + + public TransactionBuilder UseParameter(IMessage parameter) + { + Parameter = parameter; + return this; + } + + public Transaction Build() + { + var keyPair = CryptoHelper.FromPrivateKey(ByteArrayHelper.HexStringToByteArray(PrivateKey)); + var from = Address.FromPublicKey(keyPair.PublicKey).ToBase58(); + var unsignedTx = _aelfClient.GenerateTransactionAsync(from, ContractAddress, MethodName, Parameter).Result; + var signedTx = _aelfClient.SignTransaction(PrivateKey, unsignedTx); + return signedTx; + } +} \ No newline at end of file From 76d3d60d036ddcce7bfcdf7e5f6852ae6796cbff Mon Sep 17 00:00:00 2001 From: yiqi Date: Sun, 22 May 2022 02:32:34 +0800 Subject: [PATCH 41/70] Initialed APDPoSViewer as an example. --- examples/AEDPoSViewer/AEDPoSViewer.csproj | 8 +++ .../AEDPoSViewer/AEDPoSViewerConstants.cs | 6 ++ examples/AEDPoSViewer/AEDPoSViewerModule.cs | 12 ++++ examples/AEDPoSViewer/AEDPoSViewerService.cs | 38 +++++++++++++ examples/AEDPoSViewer/Program.cs | 51 ++++++++++------- examples/AEDPoSViewer/appsettings.json | 15 +++++ src/AElf.Client/AElfClient.Client.cs | 19 +++++++ src/AElf.Client/AElfClientModule.cs | 1 + src/AElf.Client/AElfClientService.cs | 57 ++++++++++++++++++- src/AElf.Client/IAElfAccountProvider.cs | 47 +++++++++++++++ src/AElf.Client/IAElfClientProvider.cs | 2 +- src/AElf.Client/IAElfClientService.cs | 8 ++- src/AElf.Client/Options/AElfAccountOptions.cs | 2 +- src/AElf.Client/Options/AElfClientOptions.cs | 2 +- src/AElf.Client/TransactionBuilder.cs | 8 +-- 15 files changed, 245 insertions(+), 31 deletions(-) create mode 100644 examples/AEDPoSViewer/AEDPoSViewerConstants.cs create mode 100644 examples/AEDPoSViewer/AEDPoSViewerModule.cs create mode 100644 examples/AEDPoSViewer/AEDPoSViewerService.cs create mode 100644 examples/AEDPoSViewer/appsettings.json create mode 100644 src/AElf.Client/IAElfAccountProvider.cs diff --git a/examples/AEDPoSViewer/AEDPoSViewer.csproj b/examples/AEDPoSViewer/AEDPoSViewer.csproj index c35049a..368da88 100644 --- a/examples/AEDPoSViewer/AEDPoSViewer.csproj +++ b/examples/AEDPoSViewer/AEDPoSViewer.csproj @@ -10,5 +10,13 @@ + + + + + + + + diff --git a/examples/AEDPoSViewer/AEDPoSViewerConstants.cs b/examples/AEDPoSViewer/AEDPoSViewerConstants.cs new file mode 100644 index 0000000..14e98e2 --- /dev/null +++ b/examples/AEDPoSViewer/AEDPoSViewerConstants.cs @@ -0,0 +1,6 @@ +namespace AEDPoSViewer; + +public class AEDPoSViewerConstants +{ + public const string ConsensusSmartContractName = "AElf.ContractNames.Consensus"; +} \ No newline at end of file diff --git a/examples/AEDPoSViewer/AEDPoSViewerModule.cs b/examples/AEDPoSViewer/AEDPoSViewerModule.cs new file mode 100644 index 0000000..9130df1 --- /dev/null +++ b/examples/AEDPoSViewer/AEDPoSViewerModule.cs @@ -0,0 +1,12 @@ +using AElf.Client; +using Volo.Abp.Modularity; + +namespace AEDPoSViewer; + +[DependsOn( + typeof(AElfClientModule) + )] +public class AEDPoSViewerModule : AbpModule +{ + +} \ No newline at end of file diff --git a/examples/AEDPoSViewer/AEDPoSViewerService.cs b/examples/AEDPoSViewer/AEDPoSViewerService.cs new file mode 100644 index 0000000..cb6f106 --- /dev/null +++ b/examples/AEDPoSViewer/AEDPoSViewerService.cs @@ -0,0 +1,38 @@ +using AElf.Client; +using AElf.Contracts.Consensus.AEDPoS; +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; + +namespace AEDPoSViewer; + +public class AEDPoSViewerService : ITransientDependency +{ + private IServiceScopeFactory ServiceScopeFactory { get; } + + public ILogger Logger { get; set; } + + public AEDPoSViewerService(IServiceScopeFactory serviceScopeFactory) + { + ServiceScopeFactory = serviceScopeFactory; + + Logger = NullLogger.Instance; + } + + public async Task RunAsync(string[] args) + { + using var scope = ServiceScopeFactory.CreateScope(); + + var clientService = scope.ServiceProvider.GetRequiredService(); + + var result = await clientService.ViewSystemAsync(AEDPoSViewerConstants.ConsensusSmartContractName, + "GetCurrentRoundInformation", new Empty(), EndpointType.MainNetMainChain.ToString()); + + var round = new Round(); + round.MergeFrom(result); + Logger.LogInformation(round.ToString()); + } +} \ No newline at end of file diff --git a/examples/AEDPoSViewer/Program.cs b/examples/AEDPoSViewer/Program.cs index c55a16d..7191b85 100644 --- a/examples/AEDPoSViewer/Program.cs +++ b/examples/AEDPoSViewer/Program.cs @@ -1,23 +1,34 @@ -using AElf; -using AElf.Client; -using AElf.Client.Dto; -using AElf.Contracts.Consensus.AEDPoS; -using Google.Protobuf; -using Google.Protobuf.WellKnownTypes; +using AEDPoSViewer; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Serilog; +using Serilog.Events; -var aelfClient = new AElfClientBuilder().UsePublicEndpoint(EndpointType.MainNetMainChain).Build(); -var tx = new TransactionBuilder(aelfClient) - .UsePrivateKey(AElfClientConstants.DefaultPrivateKey) - .UseSystemContract("AElf.ContractNames.Consensus") - .UseMethod("GetCurrentRoundInformation") - .UseParameter(new Empty()) - .Build(); +Log.Logger = new LoggerConfiguration() + .MinimumLevel.Information() + .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning) +#if DEBUG + .MinimumLevel.Override("AEDPoSViewer", LogEventLevel.Debug) +#else + .MinimumLevel.Override("AEDPoSViewer", LogEventLevel.Information) +#endif + .Enrich.FromLogContext() + .WriteTo.Async(c => c.File($"Logs/aelf-consensus-viewer-{DateTime.UtcNow:yyyy-MM-dd}.logs")) + .WriteTo.Console() + .CreateLogger(); -var result = await aelfClient.ExecuteTransactionAsync(new ExecuteTransactionDto -{ - RawTransaction = tx.ToByteArray().ToHex() -}); +using var application = AbpApplicationFactory.Create( + options => + { + options.UseAutofac(); + options.Services.AddLogging(c => c.AddSerilog()); + }); +application.Initialize(); -var round = new Round(); -round.MergeFrom(ByteArrayHelper.HexStringToByteArray(result)); -Console.WriteLine(round); \ No newline at end of file +await application.ServiceProvider + .GetRequiredService() + .RunAsync(args); + +application.Shutdown(); +Log.CloseAndFlush(); \ No newline at end of file diff --git a/examples/AEDPoSViewer/appsettings.json b/examples/AEDPoSViewer/appsettings.json new file mode 100644 index 0000000..0073548 --- /dev/null +++ b/examples/AEDPoSViewer/appsettings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + }, + "AElfClient": { + + }, + "AElfAccount":{ + + } +} \ No newline at end of file diff --git a/src/AElf.Client/AElfClient.Client.cs b/src/AElf.Client/AElfClient.Client.cs index 776fed0..c187395 100644 --- a/src/AElf.Client/AElfClient.Client.cs +++ b/src/AElf.Client/AElfClient.Client.cs @@ -141,6 +141,25 @@ public Transaction SignTransaction(string? privateKeyHex, Transaction transactio return transaction; } + + /// + /// Sign a transaction using private key. + /// + /// + /// + /// Transaction signed + public Transaction SignTransaction(byte[]? privateKey, Transaction transaction) + { + var transactionData = transaction.GetHash().ToByteArray(); + + privateKey ??= ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey); + + // Sign the hash + var signature = CryptoHelper.SignWithPrivateKey(privateKey, transactionData); + transaction.Signature = ByteString.CopyFrom(signature); + + return transaction; + } /// /// Get the account address through the public key. diff --git a/src/AElf.Client/AElfClientModule.cs b/src/AElf.Client/AElfClientModule.cs index c300af4..d727609 100644 --- a/src/AElf.Client/AElfClientModule.cs +++ b/src/AElf.Client/AElfClientModule.cs @@ -13,5 +13,6 @@ public class AElfClientModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { Configure(context.Services.GetConfiguration().GetSection("AElfClient")); + Configure(context.Services.GetConfiguration().GetSection("AElfAccount")); } } \ No newline at end of file diff --git a/src/AElf.Client/AElfClientService.cs b/src/AElf.Client/AElfClientService.cs index 06cd2f5..a625803 100644 --- a/src/AElf.Client/AElfClientService.cs +++ b/src/AElf.Client/AElfClientService.cs @@ -1,4 +1,6 @@ +using AElf.Client.Dto; using AElf.Client.Options; +using Google.Protobuf; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -7,15 +9,64 @@ namespace AElf.Client; public class AElfClientService : IAElfClientService, ITransientDependency { private readonly IAElfClientProvider _aelfClientProvider; + private readonly IAElfAccountProvider _aelfAccountProvider; private readonly AElfClientOptions _aelfClientOptions; private readonly AElfAccountOptions _aelfAccountOptions; - public AElfClientService(IAElfClientProvider aelfClientProvider, IOptionsSnapshot aelfClientOptions, - IOptionsSnapshot aelfAccountOptions) + public AElfClientService(IAElfClientProvider aelfClientProvider, IAElfAccountProvider aelfAccountProvider, + IOptionsSnapshot aelfClientOptions, IOptionsSnapshot aelfAccountOptions) { _aelfClientProvider = aelfClientProvider; + _aelfAccountProvider = aelfAccountProvider; _aelfClientOptions = aelfClientOptions.Value; _aelfAccountOptions = aelfAccountOptions.Value; - + + var clientBuilder = new AElfClientBuilder(); + foreach (var (alias, clientConfig) in aelfClientOptions.Value.ClientConfigs) + { + var client = clientBuilder + .UseEndpoint(clientConfig.Endpoint) + .ManagePeerInfo(clientConfig.UserName, clientConfig.Password) + .SetHttpTimeout(clientConfig.Timeout) + .Build(); + _aelfClientProvider.SetClient(client, alias: alias); + } + } + + public async Task ViewAsync(string contractAddress, string methodName, IMessage parameter, string clientAlias, + string accountAlias = "Default") + { + var aelfClient = _aelfClientProvider.GetClient(alias: clientAlias); + var aelfAccount = _aelfAccountProvider.GetPrivateKey(alias: accountAlias); + var tx = new TransactionBuilder(aelfClient) + .UsePrivateKey(aelfAccount) + .UseContract(contractAddress) + .UseMethod(methodName) + .UseParameter(parameter) + .Build(); + return await PerformViewAsync(aelfClient, tx); + } + + public async Task ViewSystemAsync(string systemContractName, string methodName, IMessage parameter, string clientAlias, + string accountAlias = "Default") + { + var aelfClient = _aelfClientProvider.GetClient(alias: clientAlias); + var privateKey = _aelfAccountProvider.GetPrivateKey(alias: accountAlias); + var tx = new TransactionBuilder(aelfClient) + .UsePrivateKey(privateKey) + .UseSystemContract(systemContractName) + .UseMethod(methodName) + .UseParameter(parameter) + .Build(); + return await PerformViewAsync(aelfClient, tx); + } + + private async Task PerformViewAsync(AElfClient aelfClient, Transaction tx) + { + var result = await aelfClient.ExecuteTransactionAsync(new ExecuteTransactionDto + { + RawTransaction = tx.ToByteArray().ToHex() + }); + return ByteArrayHelper.HexStringToByteArray(result); } } \ No newline at end of file diff --git a/src/AElf.Client/IAElfAccountProvider.cs b/src/AElf.Client/IAElfAccountProvider.cs new file mode 100644 index 0000000..d91cd06 --- /dev/null +++ b/src/AElf.Client/IAElfAccountProvider.cs @@ -0,0 +1,47 @@ +using Volo.Abp.DependencyInjection; + +namespace AElf.Client; + +public interface IAElfAccountProvider +{ + byte[] GetPrivateKey(string? alias = null, string? address = null); + void SetPrivateKey(byte[] privateKey, string? alias = null, string? address = null); +} + +public class AElfAccountProvider : Dictionary, IAElfAccountProvider, ISingletonDependency +{ + public AElfAccountProvider() + { + var defaultPrivateKey = ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey); + SetPrivateKey(defaultPrivateKey, "Default", Address.FromPublicKey(defaultPrivateKey).ToBase58()); + } + + public byte[] GetPrivateKey(string? alias = null, string? address = null) + { + var keys = Keys + .WhereIf(!alias.IsNullOrWhiteSpace(), a => a.Alias == alias) + .WhereIf(!address.IsNullOrWhiteSpace(), a => a.Address == address) + .ToList(); + if (keys.Count != 1) + { + throw new AElfClientException($"Failed to get private of {alias} - {address}."); + } + + return this[keys.Single()]; + } + + public void SetPrivateKey(byte[] privateKey, string? alias = null, string? address = null) + { + TryAdd(new AElfAccountInfo + { + Alias = alias, + Address = address + }, privateKey); + } +} + +public class AElfAccountInfo +{ + public string? Alias { get; set; } + public string? Address { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/IAElfClientProvider.cs b/src/AElf.Client/IAElfClientProvider.cs index 46e22cc..9df8bd1 100644 --- a/src/AElf.Client/IAElfClientProvider.cs +++ b/src/AElf.Client/IAElfClientProvider.cs @@ -38,7 +38,7 @@ public AElfClient GetClient(string? alias = null, string? environment = null, in .ToList(); if (keys.Count != 1) { - throw new AElfClientException($"Failed to get client of {alias} - {environment} - {chainId} - {chainType}"); + throw new AElfClientException($"Failed to get client of {alias} - {environment} - {chainId} - {chainType}."); } return this[keys.Single()]; diff --git a/src/AElf.Client/IAElfClientService.cs b/src/AElf.Client/IAElfClientService.cs index e92feb5..3d126f5 100644 --- a/src/AElf.Client/IAElfClientService.cs +++ b/src/AElf.Client/IAElfClientService.cs @@ -1,6 +1,12 @@ +using Google.Protobuf; + namespace AElf.Client; public interface IAElfClientService { - + Task ViewAsync(string contractAddress, string methodName, IMessage parameter, string clientAlias, + string accountAlias = "Default"); + + Task ViewSystemAsync(string systemContractName, string methodName, IMessage parameter, + string clientAlias, string accountAlias = "Default"); } \ No newline at end of file diff --git a/src/AElf.Client/Options/AElfAccountOptions.cs b/src/AElf.Client/Options/AElfAccountOptions.cs index dcc88fc..4594105 100644 --- a/src/AElf.Client/Options/AElfAccountOptions.cs +++ b/src/AElf.Client/Options/AElfAccountOptions.cs @@ -3,7 +3,7 @@ namespace AElf.Client.Options; public class AElfAccountOptions { public string KeyDirectory { get; set; } - public Dictionary AccountConfigs { get; set; } + public Dictionary AccountConfigs { get; set; } = new(); } public class AccountConfig diff --git a/src/AElf.Client/Options/AElfClientOptions.cs b/src/AElf.Client/Options/AElfClientOptions.cs index 375ec6f..082f468 100644 --- a/src/AElf.Client/Options/AElfClientOptions.cs +++ b/src/AElf.Client/Options/AElfClientOptions.cs @@ -2,7 +2,7 @@ namespace AElf.Client.Options; public class AElfClientOptions { - public Dictionary ClientConfigs { get; set; } + public Dictionary ClientConfigs { get; set; } = new(); } public class ClientConfig diff --git a/src/AElf.Client/TransactionBuilder.cs b/src/AElf.Client/TransactionBuilder.cs index 0bfdb0c..f7bbd6b 100644 --- a/src/AElf.Client/TransactionBuilder.cs +++ b/src/AElf.Client/TransactionBuilder.cs @@ -7,7 +7,7 @@ public class TransactionBuilder { private readonly AElfClient _aelfClient; - private string PrivateKey { get; set; } + private byte[] PrivateKey { get; set; } private string ContractAddress { get; set; } private string MethodName { get; set; } private IMessage Parameter { get; set; } @@ -15,10 +15,10 @@ public class TransactionBuilder public TransactionBuilder(AElfClient aelfClient) { _aelfClient = aelfClient; - PrivateKey = AElfClientConstants.DefaultPrivateKey; + PrivateKey = ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey); } - public TransactionBuilder UsePrivateKey(string privateKey) + public TransactionBuilder UsePrivateKey(byte[] privateKey) { PrivateKey = privateKey; return this; @@ -51,7 +51,7 @@ public TransactionBuilder UseParameter(IMessage parameter) public Transaction Build() { - var keyPair = CryptoHelper.FromPrivateKey(ByteArrayHelper.HexStringToByteArray(PrivateKey)); + var keyPair = CryptoHelper.FromPrivateKey(PrivateKey); var from = Address.FromPublicKey(keyPair.PublicKey).ToBase58(); var unsignedTx = _aelfClient.GenerateTransactionAsync(from, ContractAddress, MethodName, Parameter).Result; var signedTx = _aelfClient.SignTransaction(PrivateKey, unsignedTx); From cf4cafc4a33b3d731333ceb770fcfdb78d43492e Mon Sep 17 00:00:00 2001 From: yiqi Date: Wed, 25 May 2022 18:41:29 +0800 Subject: [PATCH 42/70] Now the AElfClientModule is ready for use. --- examples/AEDPoSViewer/AEDPoSViewer.csproj | 16 ++++-- .../AEDPoSViewer/AEDPoSViewerHostedService.cs | 45 +++++++++++++++ examples/AEDPoSViewer/AEDPoSViewerModule.cs | 2 +- examples/AEDPoSViewer/AEDPoSViewerService.cs | 6 +- examples/AEDPoSViewer/Program.cs | 40 ++++++++------ examples/AEDPoSViewer/appsettings.json | 49 +++++++++++++---- src/AElf.Client/AElf.Client.csproj | 3 +- src/AElf.Client/AElfClientModule.cs | 6 +- src/AElf.Client/AElfClientService.cs | 22 +------- src/AElf.Client/IAElfAccountProvider.cs | 55 ++++++++++++++++++- src/AElf.Client/IAElfClientProvider.cs | 17 +++++- .../Infrastructure/IKeyDirectoryProvider.cs | 7 +++ .../Infrastructure/KeyDirectoryProvider.cs | 24 ++++++++ src/AElf.Client/Options/AElfAccountOptions.cs | 4 +- src/AElf.Client/Options/AElfClientOptions.cs | 3 +- src/AElf.Client/TransactionBuilder.cs | 8 ++- 16 files changed, 238 insertions(+), 69 deletions(-) create mode 100644 examples/AEDPoSViewer/AEDPoSViewerHostedService.cs create mode 100644 src/AElf.Client/Infrastructure/IKeyDirectoryProvider.cs create mode 100644 src/AElf.Client/Infrastructure/KeyDirectoryProvider.cs diff --git a/examples/AEDPoSViewer/AEDPoSViewer.csproj b/examples/AEDPoSViewer/AEDPoSViewer.csproj index 368da88..607ed59 100644 --- a/examples/AEDPoSViewer/AEDPoSViewer.csproj +++ b/examples/AEDPoSViewer/AEDPoSViewer.csproj @@ -12,11 +12,19 @@ - - + + + - - + + + + + + + PreserveNewest + Always + diff --git a/examples/AEDPoSViewer/AEDPoSViewerHostedService.cs b/examples/AEDPoSViewer/AEDPoSViewerHostedService.cs new file mode 100644 index 0000000..bdb0b9c --- /dev/null +++ b/examples/AEDPoSViewer/AEDPoSViewerHostedService.cs @@ -0,0 +1,45 @@ +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Serilog; +using Volo.Abp; + +namespace AEDPoSViewer; + +public class AEDPoSViewerHostedService : IHostedService +{ + private IAbpApplicationWithInternalServiceProvider _abpApplication; + + private readonly IConfiguration _configuration; + private readonly IHostEnvironment _hostEnvironment; + + public AEDPoSViewerHostedService(IConfiguration configuration, IHostEnvironment hostEnvironment) + { + _configuration = configuration; + _hostEnvironment = hostEnvironment; + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + _abpApplication = await AbpApplicationFactory.CreateAsync(options => + { + options.Services.ReplaceConfiguration(_configuration); + options.Services.AddSingleton(_hostEnvironment); + + options.UseAutofac(); + options.Services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog()); + }); + + await _abpApplication.InitializeAsync(); + + var helloWorldService = _abpApplication.ServiceProvider.GetRequiredService(); + await helloWorldService.RunAsync(); + } + + public async Task StopAsync(CancellationToken cancellationToken) + { + await _abpApplication.ShutdownAsync(); + } +} \ No newline at end of file diff --git a/examples/AEDPoSViewer/AEDPoSViewerModule.cs b/examples/AEDPoSViewer/AEDPoSViewerModule.cs index 9130df1..2539570 100644 --- a/examples/AEDPoSViewer/AEDPoSViewerModule.cs +++ b/examples/AEDPoSViewer/AEDPoSViewerModule.cs @@ -8,5 +8,5 @@ namespace AEDPoSViewer; )] public class AEDPoSViewerModule : AbpModule { - + } \ No newline at end of file diff --git a/examples/AEDPoSViewer/AEDPoSViewerService.cs b/examples/AEDPoSViewer/AEDPoSViewerService.cs index cb6f106..7dc31b6 100644 --- a/examples/AEDPoSViewer/AEDPoSViewerService.cs +++ b/examples/AEDPoSViewer/AEDPoSViewerService.cs @@ -22,17 +22,17 @@ public AEDPoSViewerService(IServiceScopeFactory serviceScopeFactory) Logger = NullLogger.Instance; } - public async Task RunAsync(string[] args) + public async Task RunAsync() { using var scope = ServiceScopeFactory.CreateScope(); var clientService = scope.ServiceProvider.GetRequiredService(); var result = await clientService.ViewSystemAsync(AEDPoSViewerConstants.ConsensusSmartContractName, - "GetCurrentRoundInformation", new Empty(), EndpointType.MainNetMainChain.ToString()); + "GetCurrentRoundInformation", new Empty(), EndpointType.MainNetMainChain.ToString(), "Ean"); var round = new Round(); round.MergeFrom(result); - Logger.LogInformation(round.ToString()); + Logger.LogInformation($"Current round: {round.RoundNumber}"); } } \ No newline at end of file diff --git a/examples/AEDPoSViewer/Program.cs b/examples/AEDPoSViewer/Program.cs index 7191b85..badd66f 100644 --- a/examples/AEDPoSViewer/Program.cs +++ b/examples/AEDPoSViewer/Program.cs @@ -1,6 +1,6 @@ using AEDPoSViewer; using Microsoft.Extensions.DependencyInjection; -using Volo.Abp; +using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events; @@ -11,24 +11,30 @@ #if DEBUG .MinimumLevel.Override("AEDPoSViewer", LogEventLevel.Debug) #else - .MinimumLevel.Override("AEDPoSViewer", LogEventLevel.Information) + .MinimumLevel.Override("AEDPoSViewer", LogEventLevel.Information) #endif .Enrich.FromLogContext() .WriteTo.Async(c => c.File($"Logs/aelf-consensus-viewer-{DateTime.UtcNow:yyyy-MM-dd}.logs")) - .WriteTo.Console() + .WriteTo.Async(c => c.Console()) .CreateLogger(); -using var application = AbpApplicationFactory.Create( - options => - { - options.UseAutofac(); - options.Services.AddLogging(c => c.AddSerilog()); - }); -application.Initialize(); - -await application.ServiceProvider - .GetRequiredService() - .RunAsync(args); - -application.Shutdown(); -Log.CloseAndFlush(); \ No newline at end of file +try +{ + await Host.CreateDefaultBuilder(args) + .ConfigureServices(services => + { + services.AddHostedService(); + }) + .UseSerilog() + .RunConsoleAsync(); + return 0; +} +catch (Exception ex) +{ + Log.Fatal(ex, "Host terminated unexpectedly!"); + return 1; +} +finally +{ + Log.CloseAndFlush(); +} \ No newline at end of file diff --git a/examples/AEDPoSViewer/appsettings.json b/examples/AEDPoSViewer/appsettings.json index 0073548..ec1136b 100644 --- a/examples/AEDPoSViewer/appsettings.json +++ b/examples/AEDPoSViewer/appsettings.json @@ -1,15 +1,40 @@ { - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - }, - "AElfClient": { - - }, - "AElfAccount":{ - + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" } + }, + "AElfClient": { + "ClientConfigList": [ + { + "Alias": "Example", + "Endpoint": "http://192.168.0.31:6800", + "UserName": "", + "Password": "", + "Timeout": 100 + } + ] + }, + "AElfAccount":{ + "KeyDirectory": "", + "AccountConfigList": [ + { + "Alias": "Ean", + "PrivateKey": "8cc296e44d9e8881942e75a21ebc116ed3f29e39e0eaace1c92dc21e86d215c3", + "Address": "2AiXjNszZwUMdonm2RYb3GsB3aLUU3hkD1fxoazMwqPAamerLQ", + "Password": "aelftest" + }, + { + "Alias": "Test1", + "Address": "215tht8WyakoxNK4SvsR132jChydxE27RtJN8HSk1UXxuDQnmM", + "Password": "aelftest" + }, + { + "Alias": "Test2", + "PrivateKey": "5e2f12d13e4527ad1128e07db00f1614ec6b8b51662e68d4fdb42125ab384195", + } + ] + } } \ No newline at end of file diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj index bf0886e..e8dc05a 100644 --- a/src/AElf.Client/AElf.Client.csproj +++ b/src/AElf.Client/AElf.Client.csproj @@ -13,7 +13,8 @@ - + + diff --git a/src/AElf.Client/AElfClientModule.cs b/src/AElf.Client/AElfClientModule.cs index d727609..7e2fb0a 100644 --- a/src/AElf.Client/AElfClientModule.cs +++ b/src/AElf.Client/AElfClientModule.cs @@ -1,4 +1,5 @@ using AElf.Client.Options; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Autofac; using Volo.Abp.Modularity; @@ -12,7 +13,8 @@ public class AElfClientModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - Configure(context.Services.GetConfiguration().GetSection("AElfClient")); - Configure(context.Services.GetConfiguration().GetSection("AElfAccount")); + var configuration = context.Services.GetConfiguration(); + Configure(options => { configuration.GetSection("AElfClient").Bind(options); }); + Configure(options => { configuration.GetSection("AElfAccount").Bind(options); }); } } \ No newline at end of file diff --git a/src/AElf.Client/AElfClientService.cs b/src/AElf.Client/AElfClientService.cs index a625803..26dc9f6 100644 --- a/src/AElf.Client/AElfClientService.cs +++ b/src/AElf.Client/AElfClientService.cs @@ -1,7 +1,5 @@ using AElf.Client.Dto; -using AElf.Client.Options; using Google.Protobuf; -using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; namespace AElf.Client; @@ -10,27 +8,11 @@ public class AElfClientService : IAElfClientService, ITransientDependency { private readonly IAElfClientProvider _aelfClientProvider; private readonly IAElfAccountProvider _aelfAccountProvider; - private readonly AElfClientOptions _aelfClientOptions; - private readonly AElfAccountOptions _aelfAccountOptions; - public AElfClientService(IAElfClientProvider aelfClientProvider, IAElfAccountProvider aelfAccountProvider, - IOptionsSnapshot aelfClientOptions, IOptionsSnapshot aelfAccountOptions) + public AElfClientService(IAElfClientProvider aelfClientProvider, IAElfAccountProvider aelfAccountProvider) { _aelfClientProvider = aelfClientProvider; _aelfAccountProvider = aelfAccountProvider; - _aelfClientOptions = aelfClientOptions.Value; - _aelfAccountOptions = aelfAccountOptions.Value; - - var clientBuilder = new AElfClientBuilder(); - foreach (var (alias, clientConfig) in aelfClientOptions.Value.ClientConfigs) - { - var client = clientBuilder - .UseEndpoint(clientConfig.Endpoint) - .ManagePeerInfo(clientConfig.UserName, clientConfig.Password) - .SetHttpTimeout(clientConfig.Timeout) - .Build(); - _aelfClientProvider.SetClient(client, alias: alias); - } } public async Task ViewAsync(string contractAddress, string methodName, IMessage parameter, string clientAlias, @@ -46,7 +28,7 @@ public async Task ViewAsync(string contractAddress, string methodName, I .Build(); return await PerformViewAsync(aelfClient, tx); } - + public async Task ViewSystemAsync(string systemContractName, string methodName, IMessage parameter, string clientAlias, string accountAlias = "Default") { diff --git a/src/AElf.Client/IAElfAccountProvider.cs b/src/AElf.Client/IAElfAccountProvider.cs index d91cd06..98c4e34 100644 --- a/src/AElf.Client/IAElfAccountProvider.cs +++ b/src/AElf.Client/IAElfAccountProvider.cs @@ -1,4 +1,11 @@ +using AElf.Client.Options; +using AElf.OS.Node.Infrastructure; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using Nethereum.KeyStore; using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; namespace AElf.Client; @@ -10,10 +17,39 @@ public interface IAElfAccountProvider public class AElfAccountProvider : Dictionary, IAElfAccountProvider, ISingletonDependency { - public AElfAccountProvider() + private readonly IKeyDirectoryProvider _keyDirectoryProvider; + + public ILogger Logger { get; set; } + + public AElfAccountProvider(IKeyDirectoryProvider keyDirectoryProvider, + IOptionsSnapshot aelfAccountOptions) { + Logger = NullLogger.Instance; + _keyDirectoryProvider = keyDirectoryProvider; var defaultPrivateKey = ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey); SetPrivateKey(defaultPrivateKey, "Default", Address.FromPublicKey(defaultPrivateKey).ToBase58()); + + var keyStoreService = new KeyStoreService(); + + foreach (var accountConfig in aelfAccountOptions.Value.AccountConfigList) + { + if (string.IsNullOrWhiteSpace(accountConfig.PrivateKey)) + { + var keyFilePath = GetKeyFileFullPath(accountConfig.Address, aelfAccountOptions.Value.KeyDirectory); + var privateKey = AsyncHelper.RunSync(() => Task.Run(() => + { + using var textReader = File.OpenText(keyFilePath); + var json = textReader.ReadToEnd(); + return keyStoreService.DecryptKeyStoreFromJson(accountConfig.Password, json); + })); + SetPrivateKey(privateKey, accountConfig.Alias, accountConfig.Address); + } + else + { + var privateKey = ByteArrayHelper.HexStringToByteArray(accountConfig.PrivateKey); + SetPrivateKey(privateKey, accountConfig.Alias, Address.FromPublicKey(privateKey).ToBase58()); + } + } } public byte[] GetPrivateKey(string? alias = null, string? address = null) @@ -24,7 +60,7 @@ public byte[] GetPrivateKey(string? alias = null, string? address = null) .ToList(); if (keys.Count != 1) { - throw new AElfClientException($"Failed to get private of {alias} - {address}."); + throw new AElfClientException($"Failed to get private key of {alias} - {address}."); } return this[keys.Single()]; @@ -38,6 +74,21 @@ public void SetPrivateKey(byte[] privateKey, string? alias = null, string? addre Address = address }, privateKey); } + + private string GetKeyFileFullPath(string address, string configuredKeyDirectory) + { + var dirPath = GetKeystoreDirectoryPath(configuredKeyDirectory); + var filePath = Path.Combine(dirPath, address); + var filePathWithExtension = Path.ChangeExtension(filePath, ".json"); + return filePathWithExtension; + } + + private string GetKeystoreDirectoryPath(string? configuredKeyDirectory) + { + return string.IsNullOrWhiteSpace(configuredKeyDirectory) + ? Path.Combine(_keyDirectoryProvider.GetAppDataPath(), "keys") + : configuredKeyDirectory; + } } public class AElfAccountInfo diff --git a/src/AElf.Client/IAElfClientProvider.cs b/src/AElf.Client/IAElfClientProvider.cs index 9df8bd1..d138778 100644 --- a/src/AElf.Client/IAElfClientProvider.cs +++ b/src/AElf.Client/IAElfClientProvider.cs @@ -1,3 +1,5 @@ +using AElf.Client.Options; +using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; namespace AElf.Client; @@ -12,7 +14,7 @@ void SetClient(AElfClient client, string? environment = null, int? chainId = nul public class AElfClientProvider : Dictionary, IAElfClientProvider, ISingletonDependency { - public AElfClientProvider() + public AElfClientProvider(IOptionsSnapshot aelfClientOptions) { var clientBuilder = new AElfClientBuilder(); SetClient(clientBuilder.UsePublicEndpoint(EndpointType.MainNetMainChain).Build(), "MainNet", @@ -25,6 +27,16 @@ public AElfClientProvider() AElfClientConstants.SidechainId, "Sidechain", EndpointType.TestNetSidechain.ToString()); SetClient(clientBuilder.UsePublicEndpoint(EndpointType.Local).Build(), "Local", AElfClientConstants.MainChainId, "MainChain", EndpointType.Local.ToString()); + + foreach (var clientConfig in aelfClientOptions.Value.ClientConfigList) + { + var client = clientBuilder + .UseEndpoint(clientConfig.Endpoint) + .ManagePeerInfo(clientConfig.UserName, clientConfig.Password) + .SetHttpTimeout(clientConfig.Timeout) + .Build(); + SetClient(client, alias: clientConfig.Alias); + } } public AElfClient GetClient(string? alias = null, string? environment = null, int? chainId = null, @@ -38,7 +50,8 @@ public AElfClient GetClient(string? alias = null, string? environment = null, in .ToList(); if (keys.Count != 1) { - throw new AElfClientException($"Failed to get client of {alias} - {environment} - {chainId} - {chainType}."); + throw new AElfClientException( + $"Failed to get client of {alias} - {environment} - {chainId} - {chainType}."); } return this[keys.Single()]; diff --git a/src/AElf.Client/Infrastructure/IKeyDirectoryProvider.cs b/src/AElf.Client/Infrastructure/IKeyDirectoryProvider.cs new file mode 100644 index 0000000..e403192 --- /dev/null +++ b/src/AElf.Client/Infrastructure/IKeyDirectoryProvider.cs @@ -0,0 +1,7 @@ +namespace AElf.OS.Node.Infrastructure +{ + public interface IKeyDirectoryProvider + { + string GetAppDataPath(); + } +} \ No newline at end of file diff --git a/src/AElf.Client/Infrastructure/KeyDirectoryProvider.cs b/src/AElf.Client/Infrastructure/KeyDirectoryProvider.cs new file mode 100644 index 0000000..7448188 --- /dev/null +++ b/src/AElf.Client/Infrastructure/KeyDirectoryProvider.cs @@ -0,0 +1,24 @@ +using Volo.Abp.DependencyInjection; + +namespace AElf.OS.Node.Infrastructure; + +public class KeyDirectoryProvider : IKeyDirectoryProvider, ISingletonDependency +{ + private const string ApplicationFolderName = "aelf"; + private string _appDataPath; + + public string GetAppDataPath() + { + if (string.IsNullOrWhiteSpace(_appDataPath)) + { + _appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ApplicationFolderName); + + if (!Directory.Exists(_appDataPath)) + { + Directory.CreateDirectory(_appDataPath); + } + } + + return _appDataPath; + } +} \ No newline at end of file diff --git a/src/AElf.Client/Options/AElfAccountOptions.cs b/src/AElf.Client/Options/AElfAccountOptions.cs index 4594105..310f2f5 100644 --- a/src/AElf.Client/Options/AElfAccountOptions.cs +++ b/src/AElf.Client/Options/AElfAccountOptions.cs @@ -3,11 +3,13 @@ namespace AElf.Client.Options; public class AElfAccountOptions { public string KeyDirectory { get; set; } - public Dictionary AccountConfigs { get; set; } = new(); + public List AccountConfigList { get; set; } = new(); } public class AccountConfig { + public string Alias { get; set; } + public string Address { get; set; } public string Password { get; set; } public string PrivateKey { get; set; } } \ No newline at end of file diff --git a/src/AElf.Client/Options/AElfClientOptions.cs b/src/AElf.Client/Options/AElfClientOptions.cs index 082f468..1caf518 100644 --- a/src/AElf.Client/Options/AElfClientOptions.cs +++ b/src/AElf.Client/Options/AElfClientOptions.cs @@ -2,11 +2,12 @@ namespace AElf.Client.Options; public class AElfClientOptions { - public Dictionary ClientConfigs { get; set; } = new(); + public List ClientConfigList { get; set; } = new(); } public class ClientConfig { + public string Alias { get; set; } public string Endpoint { get; set; } public string UserName { get; set; } public string Password { get; set; } diff --git a/src/AElf.Client/TransactionBuilder.cs b/src/AElf.Client/TransactionBuilder.cs index f7bbd6b..699586d 100644 --- a/src/AElf.Client/TransactionBuilder.cs +++ b/src/AElf.Client/TransactionBuilder.cs @@ -1,5 +1,6 @@ using AElf.Cryptography; using Google.Protobuf; +using Volo.Abp.Threading; namespace AElf.Client; @@ -26,8 +27,8 @@ public TransactionBuilder UsePrivateKey(byte[] privateKey) public TransactionBuilder UseSystemContract(string systemContractName) { - ContractAddress = _aelfClient.GetContractAddressByNameAsync(HashHelper.ComputeFrom(systemContractName)) - .Result.ToBase58(); + ContractAddress = AsyncHelper.RunSync(async () => + (await _aelfClient.GetContractAddressByNameAsync(HashHelper.ComputeFrom(systemContractName))).ToBase58()); return this; } @@ -53,7 +54,8 @@ public Transaction Build() { var keyPair = CryptoHelper.FromPrivateKey(PrivateKey); var from = Address.FromPublicKey(keyPair.PublicKey).ToBase58(); - var unsignedTx = _aelfClient.GenerateTransactionAsync(from, ContractAddress, MethodName, Parameter).Result; + var unsignedTx = AsyncHelper.RunSync(async () => + await _aelfClient.GenerateTransactionAsync(from, ContractAddress, MethodName, Parameter)); var signedTx = _aelfClient.SignTransaction(PrivateKey, unsignedTx); return signedTx; } From 859941941eddb948ccf2c7d7ce14f8e09d8ff554 Mon Sep 17 00:00:00 2001 From: yiqi Date: Thu, 2 Jun 2022 16:22:28 +0800 Subject: [PATCH 43/70] Add AElf.Client.Abp project. --- AElf.Client.Test/ClientTest.cs | 565 ------------------ AElf.Client.sln | 30 - AElf.Client/AElf.Client.csproj | 32 - AElf.Client/Dto/BlockBodyDto.cs | 11 - AElf.Client/Dto/BlockDto.cs | 11 - AElf.Client/Dto/BlockHeaderDto.cs | 27 - AElf.Client/Dto/ChainStatusDto.cs | 29 - AElf.Client/Dto/CreateRawTransactionInput.cs | 81 --- AElf.Client/Dto/CreateRawTransactionOutput.cs | 7 - AElf.Client/Dto/CurrentRoundInformationDto.cs | 31 - AElf.Client/Dto/ExecuteRawTransactionDto.cs | 15 - AElf.Client/Dto/ExecuteTransactionDto.cs | 10 - AElf.Client/Dto/LogEventDto.cs | 13 - AElf.Client/Dto/MerklePathDto.cs | 15 - AElf.Client/Dto/NetworkInfoOutput.cs | 20 - AElf.Client/Dto/PeerDto.cs | 26 - AElf.Client/Dto/SendRawTransactionInput.cs | 20 - AElf.Client/Dto/SendRawTransactionOutput.cs | 9 - AElf.Client/Dto/SendTransactionInput.cs | 10 - AElf.Client/Dto/SendTransactionOutput.cs | 7 - AElf.Client/Dto/SendTransactionsInput.cs | 10 - AElf.Client/Dto/TaskQueueInfoDto.cs | 9 - AElf.Client/Dto/TransactionDto.cs | 19 - .../Dto/TransactionPoolStatusOutput.cs | 8 - AElf.Client/Dto/TransactionResultDto.cs | 23 - AElf.Client/Exception/AElfClientException.cs | 10 - AElf.Client/Exception/Error.cs | 38 -- .../TransactionResultDtoExtension.cs | 40 -- AElf.Client/Helper/EndpointHelper.cs | 96 --- AElf.Client/Model/KeyPairInfo.cs | 9 - .../Protobuf/Proto/aedpos_contract.proto | 26 - .../Proto/association_auth_contract.proto | 21 - AElf.Client/Protobuf/Proto/client.proto | 269 --------- .../Protobuf/Proto/cross_chain_contract.proto | 17 - .../Proto/descriptor_equivalent.proto | 8 - .../Protobuf/Proto/election_contract.proto | 148 ----- AElf.Client/Protobuf/Proto/options.proto | 38 -- .../Proto/parliament_auth_contract.proto | 26 - .../Protobuf/Proto/profit_contract.proto | 98 --- .../Proto/referendum_auth_contract.proto | 25 - .../Proto/toekn_converter_contract.proto | 26 - .../Protobuf/Proto/token_contract.proto | 136 ----- .../Protobuf/Proto/transaction_fee.proto | 44 -- .../Protobuf/Proto/treasury_contract.proto | 14 - .../Protobuf/Proto/vote_contract.proto | 78 --- AElf.Client/Service/AElfClient.cs | 285 --------- AElf.Client/Service/BlockAppService.cs | 54 -- AElf.Client/Service/ChainAppService.cs | 66 -- AElf.Client/Service/HttpService.cs | 240 -------- AElf.Client/Service/NetAppService.cs | 94 --- AElf.Client/Service/TransactionAppService.cs | 184 ------ all.sln | 14 + examples/AEDPoSViewer/AEDPoSViewer.csproj | 4 +- examples/AEDPoSViewer/AEDPoSViewerModule.cs | 2 +- examples/AEDPoSViewer/AEDPoSViewerService.cs | 4 +- protobuf/aelf/core.proto | 147 ----- protobuf/aelf/options.proto | 38 -- src/AElf.Client.Abp/AElf.Client.Abp.csproj | 17 + .../AElfClientModule.cs | 2 +- .../AElfClientService.cs | 2 +- src/AElf.Client.Abp/GlobalUsings.cs | 1 + .../IAElfAccountProvider.cs | 4 +- .../IAElfClientProvider.cs | 0 .../IAElfClientService.cs | 0 .../Infrastructure/IKeyDirectoryProvider.cs | 6 + .../Infrastructure/KeyDirectoryProvider.cs | 2 +- .../Options/AElfAccountOptions.cs | 0 .../Options/AElfClientOptions.cs | 0 .../AElf.Client.Protobuf.csproj | 3 + src/AElf.Client/AElf.Client.csproj | 9 +- .../TransactionResultDtoExtension.cs | 37 ++ .../Infrastructure/IKeyDirectoryProvider.cs | 7 - src/AElf.Client/TransactionBuilder.cs | 8 +- .../AElf.Client.Test}/AElf.Client.Test.csproj | 12 +- test/AElf.Client.Test/ClientTest.cs | 564 +++++++++++++++++ .../AElf.Client.Test}/Extensions.cs | 0 .../AElf.Client.Test}/WebAppErrorResponse.cs | 0 77 files changed, 667 insertions(+), 3344 deletions(-) delete mode 100644 AElf.Client.Test/ClientTest.cs delete mode 100644 AElf.Client.sln delete mode 100644 AElf.Client/AElf.Client.csproj delete mode 100644 AElf.Client/Dto/BlockBodyDto.cs delete mode 100644 AElf.Client/Dto/BlockDto.cs delete mode 100644 AElf.Client/Dto/BlockHeaderDto.cs delete mode 100644 AElf.Client/Dto/ChainStatusDto.cs delete mode 100644 AElf.Client/Dto/CreateRawTransactionInput.cs delete mode 100644 AElf.Client/Dto/CreateRawTransactionOutput.cs delete mode 100644 AElf.Client/Dto/CurrentRoundInformationDto.cs delete mode 100644 AElf.Client/Dto/ExecuteRawTransactionDto.cs delete mode 100644 AElf.Client/Dto/ExecuteTransactionDto.cs delete mode 100644 AElf.Client/Dto/LogEventDto.cs delete mode 100644 AElf.Client/Dto/MerklePathDto.cs delete mode 100644 AElf.Client/Dto/NetworkInfoOutput.cs delete mode 100644 AElf.Client/Dto/PeerDto.cs delete mode 100644 AElf.Client/Dto/SendRawTransactionInput.cs delete mode 100644 AElf.Client/Dto/SendRawTransactionOutput.cs delete mode 100644 AElf.Client/Dto/SendTransactionInput.cs delete mode 100644 AElf.Client/Dto/SendTransactionOutput.cs delete mode 100644 AElf.Client/Dto/SendTransactionsInput.cs delete mode 100644 AElf.Client/Dto/TaskQueueInfoDto.cs delete mode 100644 AElf.Client/Dto/TransactionDto.cs delete mode 100644 AElf.Client/Dto/TransactionPoolStatusOutput.cs delete mode 100644 AElf.Client/Dto/TransactionResultDto.cs delete mode 100644 AElf.Client/Exception/AElfClientException.cs delete mode 100644 AElf.Client/Exception/Error.cs delete mode 100644 AElf.Client/Extension/TransactionResultDtoExtension.cs delete mode 100644 AElf.Client/Helper/EndpointHelper.cs delete mode 100644 AElf.Client/Model/KeyPairInfo.cs delete mode 100644 AElf.Client/Protobuf/Proto/aedpos_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/association_auth_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/client.proto delete mode 100644 AElf.Client/Protobuf/Proto/cross_chain_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/descriptor_equivalent.proto delete mode 100644 AElf.Client/Protobuf/Proto/election_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/options.proto delete mode 100644 AElf.Client/Protobuf/Proto/parliament_auth_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/profit_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/referendum_auth_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/toekn_converter_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/token_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/transaction_fee.proto delete mode 100644 AElf.Client/Protobuf/Proto/treasury_contract.proto delete mode 100644 AElf.Client/Protobuf/Proto/vote_contract.proto delete mode 100644 AElf.Client/Service/AElfClient.cs delete mode 100644 AElf.Client/Service/BlockAppService.cs delete mode 100644 AElf.Client/Service/ChainAppService.cs delete mode 100644 AElf.Client/Service/HttpService.cs delete mode 100644 AElf.Client/Service/NetAppService.cs delete mode 100644 AElf.Client/Service/TransactionAppService.cs delete mode 100644 protobuf/aelf/core.proto delete mode 100644 protobuf/aelf/options.proto create mode 100644 src/AElf.Client.Abp/AElf.Client.Abp.csproj rename src/{AElf.Client => AElf.Client.Abp}/AElfClientModule.cs (95%) rename src/{AElf.Client => AElf.Client.Abp}/AElfClientService.cs (98%) create mode 100644 src/AElf.Client.Abp/GlobalUsings.cs rename src/{AElf.Client => AElf.Client.Abp}/IAElfAccountProvider.cs (98%) rename src/{AElf.Client => AElf.Client.Abp}/IAElfClientProvider.cs (100%) rename src/{AElf.Client => AElf.Client.Abp}/IAElfClientService.cs (100%) create mode 100644 src/AElf.Client.Abp/Infrastructure/IKeyDirectoryProvider.cs rename src/{AElf.Client => AElf.Client.Abp}/Infrastructure/KeyDirectoryProvider.cs (93%) rename src/{AElf.Client => AElf.Client.Abp}/Options/AElfAccountOptions.cs (100%) rename src/{AElf.Client => AElf.Client.Abp}/Options/AElfClientOptions.cs (100%) create mode 100644 src/AElf.Client/Extensions/TransactionResultDtoExtension.cs delete mode 100644 src/AElf.Client/Infrastructure/IKeyDirectoryProvider.cs rename {AElf.Client.Test => test/AElf.Client.Test}/AElf.Client.Test.csproj (65%) create mode 100644 test/AElf.Client.Test/ClientTest.cs rename {AElf.Client.Test => test/AElf.Client.Test}/Extensions.cs (100%) rename {AElf.Client.Test => test/AElf.Client.Test}/WebAppErrorResponse.cs (100%) diff --git a/AElf.Client.Test/ClientTest.cs b/AElf.Client.Test/ClientTest.cs deleted file mode 100644 index a934323..0000000 --- a/AElf.Client.Test/ClientTest.cs +++ /dev/null @@ -1,565 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using AElf.Cryptography; -using AElf.Types; -using AElf.Client.Dto; -using AElf.Client.Extension; -using AElf.Client.MultiToken; -using AElf.Client.Service; -using Google.Protobuf; -using Google.Protobuf.WellKnownTypes; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Shouldly; -using Volo.Abp.Threading; -using Xunit; -using Xunit.Abstractions; -using Address = AElf.Types.Address; -using Hash = AElf.Types.Hash; - -namespace AElf.Client.Test -{ - public class ClientTest - { - private const string BaseUrl = "http://192.168.196.116:8000"; - - private string _genesisAddress; - private string GenesisAddress => GetGenesisContractAddress(); - - // example contract-method-name - private string ContractMethodName => "GetContractAddressByName"; - - // Address and privateKey of a node. - private readonly string _address; - private const string PrivateKey = "cd86ab6347d8e52bbbe8532141fc59ce596268143a308d1d40fedf385528b458"; - - private AElfClient Client { get; } - private readonly ITestOutputHelper _testOutputHelper; - - private const string UserName = "test1"; - private const string Password = "test"; - - public ClientTest(ITestOutputHelper testOutputHelper) - { - _testOutputHelper = testOutputHelper; - Client = new AElfClient(BaseUrl, userName: UserName, password: Password); - - // To get address from privateKey.s - _address = Client.GetAddressFromPrivateKey(PrivateKey); - } - - #region block - - [Fact] - public async Task GetBlockHeightTest() - { - var height = await Client.GetBlockHeightAsync(); - height.ShouldBeGreaterThanOrEqualTo(1); - _testOutputHelper.WriteLine(height.ToString()); - } - - [Fact] - public async Task GetBlock_Test() - { - var height = await Client.GetBlockHeightAsync(); - var blockByHeight = await Client.GetBlockByHeightAsync(height); - var blockByHash = await Client.GetBlockByHashAsync(blockByHeight.BlockHash); - - var blockByHeightSerialized =JsonConvert.SerializeObject(blockByHeight, Formatting.Indented); - var blockByHashSerialized =JsonConvert.SerializeObject(blockByHash, Formatting.Indented); - - blockByHeightSerialized.ShouldBe(blockByHashSerialized); - blockByHeight.Header.Height.ShouldBe(height); - blockByHeight.IsComplete().ShouldBeTrue(); - - var block = JsonConvert.SerializeObject(blockByHeight, Formatting.Indented); - _testOutputHelper.WriteLine(block); - } - - [Fact] - public async Task GetBlockByHeight_Failed_Test() - { - const int timeOut = 60; - var httpService = new HttpService(timeOut); - const int heightNotExist = int.MaxValue; - var errorResponse = await httpService.GetResponseAsync( - $"{BaseUrl}/api/blockChain/blockByHeight?blockHeight={heightNotExist}&includeTransactions=false", - expectedStatusCode: HttpStatusCode.Forbidden); - errorResponse.Error.Code.ShouldBe(Error.NotFound.ToString()); - errorResponse.Error.Message.ShouldBe(Error.Message[Error.NotFound]); - var str = JsonConvert.SerializeObject(errorResponse, Formatting.Indented); - _testOutputHelper.WriteLine(str); - } - - #endregion - - #region chain - - [Fact] - public async Task GetChainStatus_Test() - { - var chainStatusDto = await Client.GetChainStatusAsync(); - - chainStatusDto.Branches.Count.ShouldBeGreaterThanOrEqualTo(1); - chainStatusDto.Branches.First().Key.ShouldNotBeNullOrWhiteSpace(); - chainStatusDto.Branches.First().Value.ShouldBeGreaterThanOrEqualTo(1); - chainStatusDto.ChainId.ShouldNotBeNullOrWhiteSpace(); - chainStatusDto.BestChainHash.ShouldNotBeNullOrWhiteSpace(); - chainStatusDto.BestChainHeight.ShouldBeGreaterThanOrEqualTo(1); - chainStatusDto.GenesisBlockHash.ShouldNotBeNullOrWhiteSpace(); - chainStatusDto.GenesisContractAddress.ShouldNotBeNullOrWhiteSpace(); - chainStatusDto.LongestChainHash.ShouldNotBeNullOrWhiteSpace(); - chainStatusDto.LongestChainHeight.ShouldBeGreaterThanOrEqualTo(1); - chainStatusDto.LastIrreversibleBlockHash.ShouldNotBeNullOrWhiteSpace(); - chainStatusDto.LastIrreversibleBlockHeight.ShouldBeGreaterThanOrEqualTo(1); - - var chainStatus = JsonConvert.SerializeObject(chainStatusDto, Formatting.Indented); - _testOutputHelper.WriteLine(chainStatus); - } - - #endregion - - #region net - - /// - /// Work in multiple nodes.(>=2) - /// - /// - [Fact(Skip = "Redo this later.")] - public async Task AddPeer_Test() - { - // add ipAddress - var addressToAdd = "192.168.199.122:7003"; - - var addSuccess = await Client.AddPeerAsync(addressToAdd, UserName, Password); - addSuccess.ShouldBeTrue(); - _testOutputHelper.WriteLine($"Added ipAddress: {addressToAdd}"); - } - - [Fact(Skip = "Redo this later.")] - public async Task RemovePeer_Test() - { - var peers = await Client.GetPeersAsync(false); - peers.ShouldNotBeEmpty(); - - var peerToRemoveAddress = peers[0].IpAddress; - var removeSuccess = await Client.RemovePeerAsync(peerToRemoveAddress, UserName, Password); - Assert.True(removeSuccess); - _testOutputHelper.WriteLine($"Removed ipAddress: {peerToRemoveAddress}"); - } - - [Fact] - public async Task GetPeers_Test() - { - var peers = await Client.GetPeersAsync(false); - Assert.True(peers != null); - var peersInfo = JsonConvert.SerializeObject(peers, Formatting.Indented); - _testOutputHelper.WriteLine(peersInfo); - } - - [Fact] - public async Task GetNetworkInfo_Test() - { - var netWorkInfo = await Client.GetNetworkInfoAsync(); - Assert.True(netWorkInfo != null); - var info = JsonConvert.SerializeObject(netWorkInfo, Formatting.Indented); - _testOutputHelper.WriteLine(info); - } - - #endregion - - #region transaction - - [Fact] - public async Task GetTaskQueueStatus_Test() - { - var taskQueueStatus = await Client.GetTaskQueueStatusAsync(); - taskQueueStatus.ShouldNotBeEmpty(); - - var queueStatus = JsonConvert.SerializeObject(taskQueueStatus, Formatting.Indented); - _testOutputHelper.WriteLine(queueStatus); - } - - [Fact] - public async Task GetTransactionPoolStatus_Test() - { - var poolStatus = await Client.GetTransactionPoolStatusAsync(); - Assert.True(poolStatus != null); - - var status = JsonConvert.SerializeObject(poolStatus, Formatting.Indented); - _testOutputHelper.WriteLine(status); - } - - [Fact] - public async Task ExecuteTransaction_Test() - { - var toAddress = await Client.GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); - var methodName = "GetNativeTokenInfo"; - var param = new Empty(); - - var transaction = await Client.GenerateTransactionAsync(_address, toAddress.ToBase58(), methodName, param); - var txWithSign = Client.SignTransaction(PrivateKey, transaction); - - var transactionResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto - { - RawTransaction = txWithSign.ToByteArray().ToHex() - }); - Assert.True(transactionResult != null); - - var tokenInfo = TokenInfo.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionResult)); - Assert.True(tokenInfo.Symbol == "ELF"); - } - - [Fact] - public async Task CreateRawTransaction_Test() - { - var address = GenesisAddress; - var status = await Client.GetChainStatusAsync(); - var height = status.BestChainHeight; - var blockHash = status.BestChainHash; - - var createRaw = await Client.CreateRawTransactionAsync(new CreateRawTransactionInput - { - From = _address, - To = address, - MethodName = ContractMethodName, - Params = new JObject - { - ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Token").Value.ToBase64() - }.ToString(), - RefBlockNumber = height, - RefBlockHash = blockHash - }); - - createRaw.RawTransaction.ShouldNotBeEmpty(); - } - - [Fact] - public async Task ExecuteRawTransaction_Test() - { - var address = GenesisAddress; - var status = await Client.GetChainStatusAsync(); - var height = status.BestChainHeight; - var blockHash = status.BestChainHash; - - var createRaw = await Client.CreateRawTransactionAsync(new CreateRawTransactionInput - { - From = _address, - To = address, - MethodName = ContractMethodName, - Params = new JObject - { - ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Consensus").Value.ToBase64() - }.ToString(), - RefBlockNumber = height, - RefBlockHash = blockHash - }); - - var transactionId = HashHelper.ComputeFrom(ByteArrayHelper.HexStringToByteArray(createRaw.RawTransaction)); - var signature = GetSignatureWith(PrivateKey, transactionId.ToByteArray()).ToHex(); - var rawTransactionResult = await Client.ExecuteRawTransactionAsync(new ExecuteRawTransactionDto - { - RawTransaction = createRaw.RawTransaction, - Signature = signature - }); - - rawTransactionResult.ShouldNotBeEmpty(); - var consensusAddress = - (await Client.GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Consensus"))) - .ToBase58(); - - var addressResult = rawTransactionResult.Trim('"'); - _testOutputHelper.WriteLine(rawTransactionResult); - addressResult.ShouldBe(consensusAddress); - } - - [Fact] - public async Task SendRawTransaction_Test() - { - var toAddress = GenesisAddress; - var status = await Client.GetChainStatusAsync(); - var height = status.BestChainHeight; - var blockHash = status.BestChainHash; - - var createRaw = await Client.CreateRawTransactionAsync(new CreateRawTransactionInput - { - From = _address, - To = toAddress, - MethodName = ContractMethodName, - Params = new JObject - { - ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Token").Value.ToBase64() - }.ToString(), - RefBlockNumber = height, - RefBlockHash = blockHash - }); - createRaw.RawTransaction.ShouldNotBeEmpty(); - - var transactionId = HashHelper.ComputeFrom(ByteArrayHelper.HexStringToByteArray(createRaw.RawTransaction)); - var signature = GetSignatureWith(PrivateKey, transactionId.ToByteArray()).ToHex(); - - var rawTransactionResult = await Client.SendRawTransactionAsync(new SendRawTransactionInput - { - Transaction = createRaw.RawTransaction, - Signature = signature, - ReturnTransaction = true - }); - - rawTransactionResult.ShouldNotBeNull(); - rawTransactionResult.Transaction.ShouldNotBeNull(); - rawTransactionResult.TransactionId.ShouldNotBeNullOrWhiteSpace(); - - var result = JsonConvert.SerializeObject(rawTransactionResult, Formatting.Indented); - _testOutputHelper.WriteLine(result); - } - - [Fact] - public async Task SendTransaction_Test() - { - var toAddress = GenesisAddress; - var methodName = ContractMethodName; - var param = HashHelper.ComputeFrom("AElf.ContractNames.Vote"); - - var transaction = await Client.GenerateTransactionAsync(_address, toAddress, methodName, param); - var txWithSign = Client.SignTransaction(PrivateKey, transaction); - - var result = await Client.SendTransactionAsync(new SendTransactionInput - { - RawTransaction = txWithSign.ToByteArray().ToHex() - }); - - result.ShouldNotBeNull(); - result.TransactionId.ShouldNotBeNull(); - _testOutputHelper.WriteLine(result.TransactionId); - } - - [Fact] - public async Task SendTransactions_Test() - { - var toAddress = GenesisAddress; - var methodName = ContractMethodName; - var param1 = HashHelper.ComputeFrom("AElf.ContractNames.Token"); - var param2 = HashHelper.ComputeFrom("AElf.ContractNames.Vote"); - - var parameters = new List {param1, param2}; - var sb = new StringBuilder(); - - foreach (var param in parameters) - { - var tx = await Client.GenerateTransactionAsync(_address, toAddress, methodName, param); - var txWithSign = Client.SignTransaction(PrivateKey, tx); - sb.Append(txWithSign.ToByteArray().ToHex() + ','); - } - - var result1 = await Client.SendTransactionsAsync(new SendTransactionsInput - { - RawTransactions = sb.ToString().Substring(0, sb.Length - 1) - }); - - Assert.True(result1 != null); - result1.Length.ShouldBe(2); - _testOutputHelper.WriteLine(JsonConvert.SerializeObject(result1)); - - } - - [Fact] - public async Task GetTransactionResult_Test() - { - var firstBlockDto = await Client.GetBlockByHeightAsync(1, true); - var transactionId = firstBlockDto.Body.Transactions.FirstOrDefault(); - - var transactionResultDto = await Client.GetTransactionResultAsync(transactionId); - Assert.True(transactionResultDto.Status == TransactionResultStatus.Mined.ToString().ToUpper()); - } - - [Fact] - public async Task GetTransactionResults_Test() - { - var firstBlockDto = await Client.GetBlockByHeightAsync(1, true); - var blockHash = firstBlockDto.BlockHash; - - var transactionResults = await Client.GetTransactionResultsAsync(blockHash, 0, 2); - foreach (var transaction in transactionResults) - { - Assert.True(transaction.Status == TransactionResultStatus.Mined.ToString().ToUpper()); - } - } - - [Fact] - public async Task GetMerklePathByTransactionId_Test() - { - var firstBlockDto = await Client.GetBlockByHeightAsync(1, true); - var transactionId = firstBlockDto.Body.Transactions.FirstOrDefault(); - var merklePathDto = await Client.GetMerklePathByTransactionIdAsync(transactionId); - Assert.True(merklePathDto != null); - - var merklePath = JsonConvert.SerializeObject(merklePathDto, Formatting.Indented); - merklePath.ShouldNotBeEmpty(); - - _testOutputHelper.WriteLine(merklePath); - } - - [Fact] - public async Task GetChainId_Test() - { - var chainId = await Client.GetChainIdAsync(); - chainId.ShouldBe(9992731); - } - - [Fact] - public async Task IsConnected_Test() - { - var isConnected = await Client.IsConnectedAsync(); - isConnected.ShouldBeTrue(); - } - - [Fact] - public async Task GetGenesisContractAddress_Test() - { - var genesisAddress = await Client.GetGenesisContractAddressAsync(); - genesisAddress.ShouldNotBeEmpty(); - - var address = await Client.GetContractAddressByNameAsync(Hash.Empty); - var genesisAddress2 = address.ToBase58(); - Assert.True(genesisAddress == genesisAddress2); - } - - [Fact] - public async Task GetFormattedAddress_Test() - { - var result = await Client.GetFormattedAddressAsync(Address.FromBase58(_address)); - _testOutputHelper.WriteLine(result); - Assert.True(result == $"ELF_{_address}_AELF"); - } - - [Fact] - public void GetNewKeyPairInfo_Test() - { - var output = Client.GenerateKeyPairInfo(); - var addressOutput = JsonConvert.SerializeObject(output); - _testOutputHelper.WriteLine(addressOutput); - } - - [Fact] - public async Task Transfer_Test() - { - var toAccount = Client.GenerateKeyPairInfo().Address; - var toAddress = await Client.GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); - var methodName = "Transfer"; - var param = new TransferInput - { - To = new Proto.Address {Value = Address.FromBase58(toAccount).Value}, - Symbol = "ELF", - Amount = 1000 - }; - - var transaction = await Client.GenerateTransactionAsync(_address, toAddress.ToBase58(), methodName, param); - var txWithSign = Client.SignTransaction(PrivateKey, transaction); - - var result = await Client.SendTransactionAsync(new SendTransactionInput - { - RawTransaction = txWithSign.ToByteArray().ToHex() - }); - - result.ShouldNotBeNull(); - _testOutputHelper.WriteLine(result.TransactionId); - - await Task.Delay(4000); - var transactionResult = await Client.GetTransactionResultAsync(result.TransactionId); - transactionResult.Status.ShouldBe(TransactionResultStatus.Mined.ToString().ToUpper()); - var transactionFees = transactionResult.GetTransactionFees(); - transactionFees.First().Key.ShouldBe("ELF"); - transactionFees.First().Value.ShouldBeGreaterThan(0L); - _testOutputHelper.WriteLine(JsonConvert.SerializeObject(transactionFees, Formatting.Indented)); - - var paramGetBalance = new GetBalanceInput - { - Symbol = "ELF", - Owner = new Proto.Address {Value = Address.FromBase58(toAccount).Value} - }; - - var transactionGetBalance = - await Client.GenerateTransactionAsync(_address, toAddress.ToBase58(), "GetBalance", paramGetBalance); - var txWithSignGetBalance = Client.SignTransaction(PrivateKey, transactionGetBalance); - - var transactionGetBalanceResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto - { - RawTransaction = txWithSignGetBalance.ToByteArray().ToHex() - }); - Assert.True(transactionResult != null); - - var balance = - GetBalanceOutput.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionGetBalanceResult)); - balance.Balance.ShouldBe(1000L); - } - - [Fact] - public void GetTransactionFee_Test() - { - var transactionResultDto = new TransactionResultDto - { - Logs = new[] - { - new LogEventDto - { - Name = "TransactionFeeCharged", - NonIndexed = Convert.ToBase64String((new TransactionFeeCharged {Symbol = "ELF", Amount = 1000}).ToByteArray()) - }, - new LogEventDto - { - Name = "ResourceTokenCharged", - NonIndexed = Convert.ToBase64String((new ResourceTokenCharged {Symbol = "READ", Amount = 800}).ToByteArray()) - }, - new LogEventDto - { - Name = "ResourceTokenCharged", - NonIndexed = Convert.ToBase64String((new ResourceTokenCharged {Symbol = "WRITE", Amount = 600}).ToByteArray()) - }, - new LogEventDto - { - Name = "ResourceTokenOwned", - NonIndexed = Convert.ToBase64String((new ResourceTokenOwned {Symbol = "READ", Amount = 200}).ToByteArray()) - } - } - }; - - var transactionFees = transactionResultDto.GetTransactionFees(); - transactionFees.Count.ShouldBe(3); - transactionFees["ELF"].ShouldBe(1000); - transactionFees["READ"].ShouldBe(800); - transactionFees["WRITE"].ShouldBe(600); - - - transactionResultDto = new TransactionResultDto(); - transactionFees = transactionResultDto.GetTransactionFees(); - transactionFees.Count.ShouldBe(0); - } - - #endregion - - #region private methods - - private string GetGenesisContractAddress() - { - if (_genesisAddress != null) return _genesisAddress; - - var statusDto = AsyncHelper.RunSync(Client.GetChainStatusAsync); - _genesisAddress = statusDto.GenesisContractAddress; - - return _genesisAddress; - } - - private ByteString GetSignatureWith(string privateKey, byte[] txData) - { - // Sign the hash - var signature = CryptoHelper.SignWithPrivateKey(ByteArrayHelper.HexStringToByteArray(privateKey), txData); - return ByteString.CopyFrom(signature); - } - - #endregion - } -} \ No newline at end of file diff --git a/AElf.Client.sln b/AElf.Client.sln deleted file mode 100644 index 84d1498..0000000 --- a/AElf.Client.sln +++ /dev/null @@ -1,30 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Client", "AElf.Client\AElf.Client.csproj", "{8812E67B-3177-4370-B8FE-7D9C77CDAACD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Client.Test", "AElf.Client.Test\AElf.Client.Test.csproj", "{5201BCB2-AF90-408F-A830-9879B889C89A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{3149BCAC-24BE-469C-88A5-139680B4DE1E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1FF8D171-87A5-4D4C-B8B4-82F0B4D9260D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8812E67B-3177-4370-B8FE-7D9C77CDAACD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8812E67B-3177-4370-B8FE-7D9C77CDAACD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8812E67B-3177-4370-B8FE-7D9C77CDAACD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8812E67B-3177-4370-B8FE-7D9C77CDAACD}.Release|Any CPU.Build.0 = Release|Any CPU - {5201BCB2-AF90-408F-A830-9879B889C89A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5201BCB2-AF90-408F-A830-9879B889C89A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5201BCB2-AF90-408F-A830-9879B889C89A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5201BCB2-AF90-408F-A830-9879B889C89A}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {5201BCB2-AF90-408F-A830-9879B889C89A} = {3149BCAC-24BE-469C-88A5-139680B4DE1E} - {8812E67B-3177-4370-B8FE-7D9C77CDAACD} = {1FF8D171-87A5-4D4C-B8B4-82F0B4D9260D} - EndGlobalSection -EndGlobal diff --git a/AElf.Client/AElf.Client.csproj b/AElf.Client/AElf.Client.csproj deleted file mode 100644 index 497bf9d..0000000 --- a/AElf.Client/AElf.Client.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - netstandard2.0 - AElf.Client - This is a C# client library, used to communicate with the AElf API. - AElf - true - - - - - - - - - - - - - - - - - none - PreserveNewest - ./Protobuf/Generated - ./Protobuf/Generated - Protobuf/Proto - - - diff --git a/AElf.Client/Dto/BlockBodyDto.cs b/AElf.Client/Dto/BlockBodyDto.cs deleted file mode 100644 index 848ad98..0000000 --- a/AElf.Client/Dto/BlockBodyDto.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace AElf.Client.Dto -{ - public class BlockBodyDto - { - public int TransactionsCount { get; set; } - - public List Transactions { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/BlockDto.cs b/AElf.Client/Dto/BlockDto.cs deleted file mode 100644 index db23a43..0000000 --- a/AElf.Client/Dto/BlockDto.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace AElf.Client.Dto -{ - public class BlockDto - { - public string BlockHash { get; set; } - - public BlockHeaderDto Header { get; set; } - - public BlockBodyDto Body { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/BlockHeaderDto.cs b/AElf.Client/Dto/BlockHeaderDto.cs deleted file mode 100644 index d07862a..0000000 --- a/AElf.Client/Dto/BlockHeaderDto.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -namespace AElf.Client.Dto -{ - public class BlockHeaderDto - { - public string PreviousBlockHash { get; set; } - - public string MerkleTreeRootOfTransactions { get; set; } - - public string MerkleTreeRootOfWorldState { get; set; } - - public string MerkleTreeRootOfTransactionState { get; set; } - - public string Extra { get; set; } - - public long Height { get; set; } - - public DateTime Time { get; set; } - - public string ChainId { get; set; } - - public string Bloom { get; set; } - - public string SignerPubkey { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/ChainStatusDto.cs b/AElf.Client/Dto/ChainStatusDto.cs deleted file mode 100644 index 76436b4..0000000 --- a/AElf.Client/Dto/ChainStatusDto.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; - -namespace AElf.Client.Dto -{ - public class ChainStatusDto - { - public string ChainId { get; set; } - - public Dictionary Branches { get; set; } - - public Dictionary NotLinkedBlocks { get; set; } - - public long LongestChainHeight { get; set; } - - public string LongestChainHash { get; set; } - - public string GenesisBlockHash { get; set; } - - public string GenesisContractAddress { get; set; } - - public string LastIrreversibleBlockHash { get; set; } - - public long LastIrreversibleBlockHeight { get; set; } - - public string BestChainHash { get; set; } - - public long BestChainHeight { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/CreateRawTransactionInput.cs b/AElf.Client/Dto/CreateRawTransactionInput.cs deleted file mode 100644 index 5966064..0000000 --- a/AElf.Client/Dto/CreateRawTransactionInput.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using AElf.Types; - -namespace AElf.Client.Dto -{ - public class CreateRawTransactionInput : IValidatableObject - { - /// - /// from address - /// - [Required] - public string From { get; set; } - - /// - /// to address - /// - [Required] - public string To { get; set; } - - /// - /// refer block height - /// - [Required] - public long RefBlockNumber { get; set; } - - /// - /// refer block hash - /// - [Required] - public string RefBlockHash { get; set; } - - /// - /// contract method name - /// - [Required] - public string MethodName { get; set; } - - /// - /// contract method parameters - /// - [Required] - public string Params { get; set; } - - public IEnumerable Validate(ValidationContext validationContext) - { - var validationResults = new List(); - try - { - Address.FromBase58(From); - } - catch - { - validationResults.Add(new ValidationResult(Error.Message[Error.InvalidAddress], - new[] {nameof(From)})); - } - - try - { - Address.FromBase58(To); - } - catch - { - validationResults.Add( - new ValidationResult(Error.Message[Error.InvalidAddress], new[] {nameof(To)})); - } - - try - { - Hash.LoadFromHex(RefBlockHash); - } - catch - { - validationResults.Add( - new ValidationResult(Error.Message[Error.InvalidBlockHash], new[] {nameof(RefBlockHash)})); - } - - return validationResults; - } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/CreateRawTransactionOutput.cs b/AElf.Client/Dto/CreateRawTransactionOutput.cs deleted file mode 100644 index 3925ed2..0000000 --- a/AElf.Client/Dto/CreateRawTransactionOutput.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AElf.Client.Dto -{ - public class CreateRawTransactionOutput - { - public string RawTransaction { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/CurrentRoundInformationDto.cs b/AElf.Client/Dto/CurrentRoundInformationDto.cs deleted file mode 100644 index 94680b6..0000000 --- a/AElf.Client/Dto/CurrentRoundInformationDto.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace AElf.Client.Dto -{ - public class RoundDto - { - public long RoundNumber { get; set; } - public long TermNumber { get; set; } - public long RoundId { get; set; } - public Dictionary RealTimeMinerInformation { get; set; } - public string ExtraBlockProducerOfPreviousRound { get; set; } - public long ConfirmedIrreversibleBlockRoundNumber { get; set; } - public long ConfirmedIrreversibleBlockHeight { get; set; } - public bool IsMinerListJustChanged { get; set; } - } - - public class MinerInRoundDto - { - public int Order { get; set; } - public int ProducedTinyBlocks { get; set; } - public DateTime ExpectedMiningTime { get; set; } - public List ActualMiningTimes { get; set; } - public string InValue { get; set; } - public string PreviousInValue { get; set; } - public string OutValue { get; set; } - public long ProducedBlocks { get; set; } - public long MissedBlocks { get; set; } - public long ImpliedIrreversibleBlockHeight { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/ExecuteRawTransactionDto.cs b/AElf.Client/Dto/ExecuteRawTransactionDto.cs deleted file mode 100644 index 85fa740..0000000 --- a/AElf.Client/Dto/ExecuteRawTransactionDto.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace AElf.Client.Dto -{ - public class ExecuteRawTransactionDto - { - /// - /// raw transaction - /// - public string RawTransaction { get; set; } - - /// - /// signature - /// - public string Signature { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/ExecuteTransactionDto.cs b/AElf.Client/Dto/ExecuteTransactionDto.cs deleted file mode 100644 index 255fa94..0000000 --- a/AElf.Client/Dto/ExecuteTransactionDto.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace AElf.Client.Dto -{ - public class ExecuteTransactionDto - { - /// - /// raw transaction - /// - public string RawTransaction { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/LogEventDto.cs b/AElf.Client/Dto/LogEventDto.cs deleted file mode 100644 index a856231..0000000 --- a/AElf.Client/Dto/LogEventDto.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace AElf.Client.Dto -{ - public class LogEventDto - { - public string Address { get; set; } - - public string Name { get; set; } - - public string[] Indexed { get; set; } - - public string NonIndexed { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/MerklePathDto.cs b/AElf.Client/Dto/MerklePathDto.cs deleted file mode 100644 index 6880ea5..0000000 --- a/AElf.Client/Dto/MerklePathDto.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; - -namespace AElf.Client.Dto -{ - public class MerklePathDto - { - public List MerklePathNodes; - } - - public class MerklePathNodeDto - { - public string Hash { get; set; } - public bool IsLeftChildNode { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/NetworkInfoOutput.cs b/AElf.Client/Dto/NetworkInfoOutput.cs deleted file mode 100644 index 0bf5f6f..0000000 --- a/AElf.Client/Dto/NetworkInfoOutput.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace AElf.Client.Dto -{ - public class NetworkInfoOutput - { - /// - /// node version - /// - public string Version { get; set; } - - /// - /// network protocol version - /// - public int ProtocolVersion { get; set; } - - /// - /// total number of open connections between this node and other nodes - /// - public int Connections { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/PeerDto.cs b/AElf.Client/Dto/PeerDto.cs deleted file mode 100644 index 297ba38..0000000 --- a/AElf.Client/Dto/PeerDto.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; -using Google.Protobuf.WellKnownTypes; - -namespace AElf.Client.Dto -{ - public class PeerDto - { - public string IpAddress { get; set; } - public int ProtocolVersion { get; set; } - public long ConnectionTime { get; set; } - public string ConnectionStatus { get; set; } - public bool Inbound { get; set; } - public int BufferedTransactionsCount { get; set; } - public int BufferedBlocksCount { get; set; } - public int BufferedAnnouncementsCount { get; set; } - public List RequestMetrics { get; set; } - } - - public class RequestMetric - { - public long RoundTripTime { get; set; } - public string MethodName { get; set; } - public string Info { get; set; } - public string RequestTime { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/SendRawTransactionInput.cs b/AElf.Client/Dto/SendRawTransactionInput.cs deleted file mode 100644 index a3896a9..0000000 --- a/AElf.Client/Dto/SendRawTransactionInput.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace AElf.Client.Dto -{ - public class SendRawTransactionInput - { - /// - /// raw transaction - /// - public string Transaction { get; set; } - - /// - /// signature - /// - public string Signature { get; set; } - - /// - /// return transaction detail or not - /// - public bool ReturnTransaction { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/SendRawTransactionOutput.cs b/AElf.Client/Dto/SendRawTransactionOutput.cs deleted file mode 100644 index 77600d3..0000000 --- a/AElf.Client/Dto/SendRawTransactionOutput.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AElf.Client.Dto -{ - public class SendRawTransactionOutput - { - public string TransactionId { get; set; } - - public TransactionDto Transaction { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/SendTransactionInput.cs b/AElf.Client/Dto/SendTransactionInput.cs deleted file mode 100644 index 75be53d..0000000 --- a/AElf.Client/Dto/SendTransactionInput.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace AElf.Client.Dto -{ - public class SendTransactionInput - { - /// - /// raw transaction - /// - public string RawTransaction { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/SendTransactionOutput.cs b/AElf.Client/Dto/SendTransactionOutput.cs deleted file mode 100644 index fefc1f2..0000000 --- a/AElf.Client/Dto/SendTransactionOutput.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AElf.Client.Dto -{ - public class SendTransactionOutput - { - public string TransactionId { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/SendTransactionsInput.cs b/AElf.Client/Dto/SendTransactionsInput.cs deleted file mode 100644 index d7808b5..0000000 --- a/AElf.Client/Dto/SendTransactionsInput.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace AElf.Client.Dto -{ - public class SendTransactionsInput - { - /// - /// raw transactions - /// - public string RawTransactions { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/TaskQueueInfoDto.cs b/AElf.Client/Dto/TaskQueueInfoDto.cs deleted file mode 100644 index 30cb32c..0000000 --- a/AElf.Client/Dto/TaskQueueInfoDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AElf.Client.Dto -{ - public class TaskQueueInfoDto - { - public string Name { get; set; } - - public int Size { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/TransactionDto.cs b/AElf.Client/Dto/TransactionDto.cs deleted file mode 100644 index ccecb6e..0000000 --- a/AElf.Client/Dto/TransactionDto.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace AElf.Client.Dto -{ - public class TransactionDto - { - public string From { get; set; } - - public string To { get; set; } - - public long RefBlockNumber { get; set; } - - public string RefBlockPrefix { get; set; } - - public string MethodName { get; set; } - - public string Params { get; set; } - - public string Signature { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/TransactionPoolStatusOutput.cs b/AElf.Client/Dto/TransactionPoolStatusOutput.cs deleted file mode 100644 index 19434a1..0000000 --- a/AElf.Client/Dto/TransactionPoolStatusOutput.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace AElf.Client.Dto -{ - public class TransactionPoolStatusOutput - { - public int Queued { get; set; } - public int Validated { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Dto/TransactionResultDto.cs b/AElf.Client/Dto/TransactionResultDto.cs deleted file mode 100644 index 7f0cdfd..0000000 --- a/AElf.Client/Dto/TransactionResultDto.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace AElf.Client.Dto -{ - public class TransactionResultDto - { - public string TransactionId { get; set; } - - public string Status { get; set; } - - public LogEventDto[] Logs { get; set; } - - public string Bloom { get; set; } - - public long BlockNumber { get; set; } - - public string BlockHash { get; set; } - - public TransactionDto Transaction { get; set; } - - public string ReturnValue { get; set; } - - public string Error { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Exception/AElfClientException.cs b/AElf.Client/Exception/AElfClientException.cs deleted file mode 100644 index 6262a0f..0000000 --- a/AElf.Client/Exception/AElfClientException.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace AElf.Client -{ - public class AElfClientException : System.Exception - { - public AElfClientException(string message) : base(message) - { - - } - } -} \ No newline at end of file diff --git a/AElf.Client/Exception/Error.cs b/AElf.Client/Exception/Error.cs deleted file mode 100644 index fac133a..0000000 --- a/AElf.Client/Exception/Error.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Collections.Generic; - -namespace AElf.Client -{ - public class Error - { - public const int NotFound = 20001; - public const int InvalidAddress = 20002; - public const int InvalidBlockHash = 20003; - public const int InvalidTransactionId = 20004; - public const int InvalidProposalId = 20005; - public const int InvalidOffset = 20006; - public const int InvalidLimit = 20007; - public const int InvalidTransaction = 20008; - public const int CannotBroadcastTransaction = 20009; - public const int InvalidContractAddress = 20010; - public const int NoMatchMethodInContractAddress = 20011; - public const int InvalidParams = 20012; - public const int InvalidSignature = 20013; - - public static readonly Dictionary Message = new Dictionary - { - {NotFound, "Not found"}, - {InvalidAddress, "Invalid address format"}, - {InvalidBlockHash, "Invalid block hash format"}, - {InvalidTransactionId, "Invalid Transaction id format"}, - {InvalidProposalId, "Invalid proposal id format"}, - {InvalidOffset, "Offset must greater than or equal to 0"}, - {InvalidLimit, "Limit must between 0 and 100"}, - {InvalidTransaction, "Invalid transaction information"}, - {CannotBroadcastTransaction, "Sync still in progress, cannot send transactions"}, - {InvalidContractAddress, "Invalid contract address"}, - {NoMatchMethodInContractAddress, "No match method in contract address"}, - {InvalidParams, "Invalid params"}, - {InvalidSignature, "Invalid signature"} - }; - } -} \ No newline at end of file diff --git a/AElf.Client/Extension/TransactionResultDtoExtension.cs b/AElf.Client/Extension/TransactionResultDtoExtension.cs deleted file mode 100644 index 4dd8bdd..0000000 --- a/AElf.Client/Extension/TransactionResultDtoExtension.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using AElf.Client.Dto; -using AElf.Client.MultiToken; -using Google.Protobuf; - -namespace AElf.Client.Extension -{ - public static class TransactionResultDtoExtension - { - public static Dictionary GetTransactionFees(this TransactionResultDto transactionResultDto) - { - var result = new Dictionary(); - - var transactionFeeLogs = - transactionResultDto.Logs?.Where(l => l.Name == nameof(TransactionFeeCharged)).ToList(); - if (transactionFeeLogs != null) - { - foreach (var transactionFee in transactionFeeLogs.Select(transactionFeeLog => - TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) - { - result.Add(transactionFee.Symbol, transactionFee.Amount); - } - } - - var resourceTokenLogs = - transactionResultDto.Logs?.Where(l => l.Name == nameof(ResourceTokenCharged)).ToList(); - if (resourceTokenLogs != null) - { - foreach (var resourceToken in resourceTokenLogs.Select(transactionFeeLog => - ResourceTokenCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) - { - result.Add(resourceToken.Symbol, resourceToken.Amount); - } - } - - return result; - } - } -} \ No newline at end of file diff --git a/AElf.Client/Helper/EndpointHelper.cs b/AElf.Client/Helper/EndpointHelper.cs deleted file mode 100644 index 8c6147d..0000000 --- a/AElf.Client/Helper/EndpointHelper.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System.Linq; -using System.Net; -using System.Net.Sockets; - -namespace AElf.Client.Helper -{ - public static class EndpointHelper - { - public static bool TryParse(string endpointString, out DnsEndPoint endpoint, - int defaultPort = 6800) - { - endpoint = null; - - if (string.IsNullOrEmpty(endpointString) || endpointString.Trim().Length == 0) - return false; - - if (defaultPort != -1 && (defaultPort < IPEndPoint.MinPort || defaultPort > IPEndPoint.MaxPort)) - return false; - - string[] values = endpointString.Split(new[] {':'}); - string host; - int port = -1; - - if (values.Length <= 2) - { - // ipv4 or hostname - host = values[0]; - - if (values.Length == 1) - { - port = defaultPort; - } - else - { - var parsedPort = GetPort(values[1]); - - if (parsedPort == 0) - return false; - - port = parsedPort; - } - } - else if (values.Length > 2) - { - //ipv6 - //could be [a:b:c]:d - if (values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]")) - { - host = string.Join(":", values.Take(values.Length - 1).ToArray()); - var parsedPort = GetPort(values[values.Length - 1]); - - if (parsedPort == 0) - return false; - } - else // [a:b:c] or a:b:c - { - host = endpointString; - port = defaultPort; - } - } - else - { - return false; - } - - if (port == -1) - return false; - - // we leave semantic analysis of the ip/hostname to lower levels. - endpoint = new PeerEndpoint(host, port); - - return true; - } - - private static int GetPort(string p) - { - if (!int.TryParse(p, out int port) || port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort) - return 0; - - return port; - } - } - - public class PeerEndpoint : DnsEndPoint - { - public PeerEndpoint(string host, int port) - : base(host, port, AddressFamily.Unspecified) - { - } - - public override string ToString() - { - return Host + ":" + Port; - } - } -} \ No newline at end of file diff --git a/AElf.Client/Model/KeyPairInfo.cs b/AElf.Client/Model/KeyPairInfo.cs deleted file mode 100644 index dda2aae..0000000 --- a/AElf.Client/Model/KeyPairInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AElf.Client.Model -{ - public class KeyPairInfo - { - public string PrivateKey { get; set; } - public string PublicKey { get; set; } - public string Address { get; set; } - } -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/aedpos_contract.proto b/AElf.Client/Protobuf/Proto/aedpos_contract.proto deleted file mode 100644 index b4e1c4c..0000000 --- a/AElf.Client/Protobuf/Proto/aedpos_contract.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "AElf.Client.Consensus.AEDPoS"; - -//aedpos_contract -message MinerList { - // The miners public key list. - repeated bytes pubkeys = 1; -} - -message PubkeyList { - // Candidates’ public keys - repeated bytes value = 1; -} - -message MinerListWithRoundNumber { - // The list of miners. - MinerList miner_list = 1; - // The round number. - int64 round_number = 2; -} - -message GetMinerListInput { - // The term number. - int64 term_number = 1; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/association_auth_contract.proto b/AElf.Client/Protobuf/Proto/association_auth_contract.proto deleted file mode 100644 index 67602cd..0000000 --- a/AElf.Client/Protobuf/Proto/association_auth_contract.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; - -import "client.proto"; - -option csharp_namespace = "AElf.Client.AssociationAuth"; - -// association_auth_contract -message Organization{ - // Indicates if proposals need authority to be created. - bool proposer_authority_required = 1; - // The organization address. - client.Address organization_address = 2; - // The organization id. - client.Hash organization_hash = 3; - // The threshold for releasing the proposal. - client.ProposalReleaseThreshold proposal_release_threshold = 4; - // Indicates if parliament member can propose to this organization. - bool parliament_member_proposing_allowed = 5; - // The creation token is for organization address generation. - client.Hash creation_token = 6; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/client.proto b/AElf.Client/Protobuf/Proto/client.proto deleted file mode 100644 index 2e2ce6e..0000000 --- a/AElf.Client/Protobuf/Proto/client.proto +++ /dev/null @@ -1,269 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "AElf.Client.Proto"; - -package client; - -import "google/protobuf/timestamp.proto"; - -message Address -{ - bytes value = 1; -} - -message Hash -{ - bytes value = 1; -} - -message MerklePath { - repeated MerklePathNode merkle_path_nodes = 1; -} - -message MerklePathNode{ - Hash hash = 1; - bool is_left_child_node = 2; -} - -message BinaryMerkleTree { - repeated Hash nodes = 1; - Hash root = 2; - int32 leaf_count = 3; -} - -message ScopedStatePath { - Address address = 1; - StatePath path = 2; -} - -message StatePath { - repeated string parts = 1; -} - -message SmartContractRegistration { - sint32 category = 1; - bytes code = 2; - Hash code_hash = 3; - bool is_system_contract = 4; - int32 version = 5; -} - -//acs0 -message ContractInfo -{ - // The serial number of the contract. - int64 serial_number = 1; - // The author of the contract, this is the person who deployed the contract. - client.Address author = 2; - // The category of contract code(0: C#). - sint32 category = 3; - // The hash of the contract code. - client.Hash code_hash = 4; - // Whether it is a system contract. - bool is_system_contract = 5; - // The version of the current contract. - int32 version = 6; -} - -//acs1 -message MethodFees { - // The name of the method to be charged. - string method_name = 1; - // List of fees to be charged. - repeated MethodFee fees = 2; - // Optional based on the implementation of SetMethodFee method. - bool is_size_fee_free = 3; -} - -message MethodFee { - // The name of the method to be charged. - string method_name = 1; - // List of fees to be charged. - repeated MethodFee fees = 2; - // Optional based on the implementation of SetMethodFee method. - bool is_size_fee_free = 3; -} - -//acs2 -message ResourceInfo { - // The state path that depends on when writing. - repeated client.ScopedStatePath write_paths = 1; - // The state path that depends on when reading. - repeated client.ScopedStatePath read_paths = 2; - // Whether the transaction is not executed in parallel. - bool non_parallelizable = 3; -} - -// acs3 -message ProposalOutput { - // The id of the proposal. - client.Hash proposal_id = 1; - // The method that this proposal will call when being released. - string contract_method_name = 2; - // The address of the target contract. - client.Address to_address = 3; - // The parameters of the release transaction. - bytes params = 4; - // The date at which this proposal will expire. - google.protobuf.Timestamp expired_time = 5; - // The address of this proposals organization. - client.Address organization_address = 6; - // The address of the proposer of this proposal. - client.Address proposer = 7; - // Indicates if this proposal is releasable. - bool to_be_released = 8; - // Approval count for this proposal. - int64 approval_count = 9; - // Rejection count for this proposal. - int64 rejection_count = 10; - // Abstention count for this proposal. - int64 abstention_count = 11; -} - -message ProposalReleaseThreshold { - // The value for the minimum approval threshold. - int64 minimal_approval_threshold = 1; - // The value for the maximal rejection threshold. - int64 maximal_rejection_threshold = 2; - // The value for the maximal abstention threshold. - int64 maximal_abstention_threshold = 3; - // The value for the minimal vote threshold. - int64 minimal_vote_threshold = 4; -} - -message ProposerWhiteList{ - // The address of the proposers - repeated Address proposers = 1; -} - -//acs4 - -message ValidationResult { - // Is successful. - bool success = 1; - // The error message. - string message = 2; - // Whether to trigger mining again. - bool is_re_trigger = 3; -} - -//acs5 -message MethodCallingThreshold { - // The threshold for method calling, token symbol -> amount. - map symbol_to_amount = 1; - // The type of threshold check. - ThresholdCheckType threshold_check_type = 2; -} - -enum ThresholdCheckType { - // Check balance only. - BALANCE = 0; - // Check balance and allowance at the same time. - ALLOWANCE = 1; -} - -message SideChainIndexingInformationList { - // A list contains indexing information of side chains. - repeated SideChainIndexingInformation indexing_information_list = 1; -} - -message SideChainIndexingInformation { - // The side chain id. - int32 chain_id = 1; - // The indexed height. - int64 indexed_height = 2; -} - -message CrossChainBlockData { - // The side chain block data list to index. - repeated SideChainBlockData side_chain_block_data_list = 1; - // The parent chain block data list to index. - repeated ParentChainBlockData parent_chain_block_data_list = 2; -} - -message SideChainBlockData { - // The height of side chain block. - int64 height = 1; - // The hash of side chain block. - client.Hash block_header_hash = 2; - // The merkle tree root computing from transactions status in side chain block. - client.Hash transaction_status_merkle_tree_root = 3; - // The id of side chain. - int32 chain_id = 4; -} - -message ParentChainBlockData { - // The height of parent chain. - int64 height = 1; - // The merkle tree root computing from side chain roots. - CrossChainExtraData cross_chain_extra_data = 2; - // The parent chain id. - int32 chain_id = 3; - // The merkle tree root computing from transactions status in parent chain block. - client.Hash transaction_status_merkle_tree_root = 4; - // Indexed block height from side chain and merkle path for this side chain block - map indexed_merkle_path = 5; - // Extra data map. - map extra_data = 6; -} - -message CrossChainExtraData { - // Merkle tree root of side chain block transaction status root - Hash transaction_status_merkle_tree_root = 1; -} - -message CrossChainMerkleProofContext { - // The height of parent chain bound up with side chain. - int64 bound_parent_chain_height = 1; - // The merkle path generated from parent chain. - client.MerklePath merkle_path_from_parent_chain = 2; -} - -message ChainInitializationData { - // The id of side chain. - int32 chain_id = 1; - // The side chain creator. - client.Address creator = 2; - // The timestamp for side chain creation. - google.protobuf.Timestamp creation_timestamp = 3; - // The height of side chain creation on parent chain. - int64 creation_height_on_parent_chain = 4; - // Creator privilege boolean flag: True if chain creator privilege preserved, otherwise false. - bool chain_creator_privilege_preserved = 5; - // Parent chain token contract address. - client.Address parent_chain_token_contract_address = 6; - // Initial consensus information. - ChainInitializationConsensusInfo chain_initialization_consensus_info = 7; - // The native token info. - bytes native_token_info_data = 8; - // The resource token information. - ResourceTokenInfo resource_token_info = 9; - // The chain primary token information. - ChainPrimaryTokenInfo chain_primary_token_info = 10; -} - -message ResourceTokenInfo{ - // The resource token information. - bytes resource_token_list_data = 1; - // The initial resource token amount. - map initial_resource_amount = 2; -} - -message ChainPrimaryTokenInfo{ - // The side chain primary token data. - bytes chain_primary_token_data = 1; - // The side chain primary token initial issue list. - repeated SideChainTokenInitialIssue side_chain_token_initial_issue_list = 2; -} - -message ChainInitializationConsensusInfo{ - // Initial consensus data. - bytes initial_consensus_data = 1; -} - -message SideChainTokenInitialIssue{ - // The account that will be issued. - client.Address address = 1; - // The amount that will be issued. - int64 amount = 2; -} diff --git a/AElf.Client/Protobuf/Proto/cross_chain_contract.proto b/AElf.Client/Protobuf/Proto/cross_chain_contract.proto deleted file mode 100644 index 32228d8..0000000 --- a/AElf.Client/Protobuf/Proto/cross_chain_contract.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "AElf.Client.CrossChain"; - -import "client.proto"; - -//cross_chain_contract -message VerifyTransactionInput { - // The cross chain transaction id to verify. - client.Hash transaction_id = 1; - // The merkle path of the transaction. - client.MerklePath path = 2; - // The height of parent chain that indexing this transaction. - int64 parent_chain_height = 3; - // The chain if to verify. - int32 verified_chain_id = 4; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/descriptor_equivalent.proto b/AElf.Client/Protobuf/Proto/descriptor_equivalent.proto deleted file mode 100644 index fa6bae6..0000000 --- a/AElf.Client/Protobuf/Proto/descriptor_equivalent.proto +++ /dev/null @@ -1,8 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "AElf.Client.Runtime"; - -//fileDescriptor_equivalent -message FileDescriptorSet { - repeated bytes file = 1; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/election_contract.proto b/AElf.Client/Protobuf/Proto/election_contract.proto deleted file mode 100644 index 2e94912..0000000 --- a/AElf.Client/Protobuf/Proto/election_contract.proto +++ /dev/null @@ -1,148 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "AElf.Client.Election"; - -import "google/protobuf/timestamp.proto"; -import "client.proto"; - -//election_contract -message CandidateInformation { - // Candidate’s public key. - string pubkey = 1; - // The number of terms that the candidate is elected. - repeated int64 terms = 2; - // The number of blocks the candidate has produced. - int64 produced_blocks = 3; - // The time slot for which the candidate failed to produce blocks. - int64 missed_time_slots = 4; - // The count of continual appointment. - int64 continual_appointment_count = 5; - // The transaction id when the candidate announced. - client.Hash announcement_transaction_id = 6; - // Indicate whether the candidate can be elected in the current term. - bool is_current_candidate = 7; -} - -message GetTermSnapshotInput { - // The term number. - int64 term_number = 1; -} - -message TermSnapshot { - // The end round number of this term. - int64 end_round_number = 1; - // The number of blocks mined in this term. - int64 mined_blocks = 2; - // The election result, candidates’ public key -> number of votes. - map election_result = 3; -} - -message GetElectionResultInput { - // The term number. - int64 term_number = 1; -} - -message ElectionResult { - // The term number - int64 term_number = 1; - // The election result, candidates’ public key -> number of votes. - map results = 2; - // Whether an election is currently being held. - bool is_active = 3; -} - -message ElectorVote { - // The active voting record ids. - repeated client.Hash active_voting_record_ids = 1; - // The voting record ids that were withdrawn. - repeated client.Hash withdrawn_voting_record_ids = 2; - // The total number of active votes. - int64 active_voted_votes_amount = 3; - // The total number of votes (including the number of votes withdrawn). - int64 all_voted_votes_amount = 4; - // The active voting records. - repeated ElectionVotingRecord active_voting_records = 5; - // The voting records that were withdrawn. - repeated ElectionVotingRecord withdrawn_votes_records = 6; - // Public key for voter. - bytes pubkey = 7; -} - -message ElectionVotingRecord { - // The address of voter. - client.Address voter = 1; - // The public key of candidate. - string candidate = 2; - // Amount of voting. - int64 amount = 3; - // The term number of voting. - int64 term_number = 4; - // The vote id. - client.Hash vote_id = 5; - // Vote lock time. - int64 lock_time = 6; - // The unlock timestamp. - google.protobuf.Timestamp unlock_timestamp = 7; - // The withdraw timestamp. - google.protobuf.Timestamp withdraw_timestamp = 8; - // The vote timestamp. - google.protobuf.Timestamp vote_timestamp = 9; - // Indicates if the vote has been withdrawn. - bool is_withdrawn = 10; - // Vote weight for sharing bonus. - int64 weight = 11; - // Whether vote others. - bool is_change_target = 12; -} - -message CandidateVote { - // The active voting record ids obtained. - repeated client.Hash obtained_active_voting_record_ids = 1; - // The active voting record ids that were withdrawn. - repeated client.Hash obtained_withdrawn_voting_record_ids = 2; - // The total number of active votes obtained. - int64 obtained_active_voted_votes_amount = 3; - // The total number of votes obtained. - int64 all_obtained_voted_votes_amount = 4; - // The active voting records. - repeated ElectionVotingRecord obtained_active_voting_records = 5; - // The voting records that were withdrawn. - repeated ElectionVotingRecord obtained_withdrawn_votes_records = 6; - // Public key for candidate. - bytes pubkey = 7; -} - -message GetWelfareRewardAmountSampleInput { - // Token lock time. - repeated int64 value = 1; -} - -message GetWelfareRewardAmountSampleOutput { - // The weight calculated. - repeated int64 value = 1; -} - -message PageInformation { - // The start index. - int32 start = 1; - // The number of records. - int32 length = 2; -} - -message CandidateDetail { - // The candidate information. - CandidateInformation candidate_information = 1; - // The number of votes a candidate has obtained. - int64 obtained_votes_amount = 2; -} - -message GetPageableCandidateInformationOutput { - // The details of the candidates. - repeated CandidateDetail value = 1; -} - -message DataCenterRankingList { - // The top n * 5 candidates with vote amount, candidate public key -> vote amount. - map data_centers = 1; - int64 minimum_votes = 2; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/options.proto b/AElf.Client/Protobuf/Proto/options.proto deleted file mode 100644 index b16a05a..0000000 --- a/AElf.Client/Protobuf/Proto/options.proto +++ /dev/null @@ -1,38 +0,0 @@ -syntax = "proto3"; - -package client; - -import "google/protobuf/descriptor.proto"; - -option csharp_namespace = "AElf.Client"; - -// All aelf custom options field numbers are like 50yxxx -// where y stands for the custom options type: -// 0 - FileOptions -// 1 - MessageOptions -// 2 - FieldOptions -// 3 - EnumOptions -// 4 - EnumValueOptions -// 5 - ServiceOptions -// 6 - MethodOptions - -extend google.protobuf.FileOptions { - string identity = 500001; -} - -extend google.protobuf.ServiceOptions { - repeated string base = 505001; - string csharp_state = 505030; -} - -extend google.protobuf.MethodOptions { - bool is_view = 506001; -} - -extend google.protobuf.MessageOptions { - bool is_event = 50100; -} - -extend google.protobuf.FieldOptions { - bool is_indexed = 502001; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/parliament_auth_contract.proto b/AElf.Client/Protobuf/Proto/parliament_auth_contract.proto deleted file mode 100644 index 68b3aae..0000000 --- a/AElf.Client/Protobuf/Proto/parliament_auth_contract.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; - -import "client.proto"; - -option csharp_namespace = "AElf.Client.ParliamentAuth"; - -//parliament_auth -message ProposalIdList{ - // The list of proposal ids. - repeated client.Hash proposal_ids = 1; -} - -message Organization { - // Indicates if proposals need authority to be created. - bool proposer_authority_required = 1; - // The organization address. - client.Address organization_address = 2; - // The organization id. - client.Hash organization_hash = 3; - // The threshold for releasing the proposal. - client.ProposalReleaseThreshold proposal_release_threshold = 4; - // Indicates if parliament member can propose to this organization. - bool parliament_member_proposing_allowed = 5; - // The creation token is for organization address generation. - client.Hash creation_token = 6; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/profit_contract.proto b/AElf.Client/Protobuf/Proto/profit_contract.proto deleted file mode 100644 index 3910e0d..0000000 --- a/AElf.Client/Protobuf/Proto/profit_contract.proto +++ /dev/null @@ -1,98 +0,0 @@ -syntax = "proto3"; - -import "client.proto"; - -option csharp_namespace = "AElf.Client.Profit"; - -//profit_contract -message CreatedSchemeIds { - // The scheme ids. - repeated client.Hash scheme_ids = 1; -} - -message GetManagingSchemeIdsInput { - // The manager address. - client.Address manager = 1; -} - -message SchemeBeneficiaryShare { - // The id of the sub scheme. - client.Hash scheme_id = 1; - // The weight of the sub scheme. - int64 shares = 2; -} - -message Scheme { - // The virtual address of the scheme. - client.Address virtual_address = 1; - // The total weight of the scheme. - int64 total_shares = 2; - // The manager of the scheme. - client.Address manager = 3; - // The current period. - int64 current_period = 4; - // Sub schemes information. - repeated SchemeBeneficiaryShare sub_schemes = 5; - // Whether you can directly remove the beneficiary. - bool can_remove_beneficiary_directly = 6; - // Period of profit distribution. - int64 profit_receiving_due_period_count = 7; - // Whether all the schemes balance will be distributed during distribution each period. - bool is_release_all_balance_every_time_by_default = 8; - // The is of the scheme. - client.Hash scheme_id = 9; - // Delay distribute period. - int32 delay_distribute_period_count = 10; - // Record the scheme's current total share for deferred distribution of benefits, period -> total shares. - map cached_delay_total_shares = 11; - // The received token symbols. - repeated string received_token_symbols = 12; -} - -message SchemePeriod { - // The scheme id. - client.Hash scheme_id = 1; - // The period number. - int64 period = 2; -} - -message DistributedProfitsInfo { - // The total amount of shares in this scheme at the current period. - int64 total_shares = 1; - // The contributed amount in this scheme at the current period. - map amounts_map = 2; - // Whether released. - bool is_released = 3; -} - -message GetProfitDetailsInput { - // The scheme id. - client.Hash scheme_id = 1; - // The address of beneficiary. - client.Address beneficiary = 2; -} - -message ProfitDetails { - // The profit information. - repeated ProfitDetail details = 1; -} - -message ProfitDetail { - // The start period number. - int64 start_period = 1; - // The end period number. - int64 end_period = 2; - // The weight of the proceeds on the current period of the scheme. - int64 shares = 3; - // The last period number that the beneficiary received the profit. - int64 last_profit_period = 4; - // Whether the weight has been removed. - bool is_weight_removed = 5; -} - -message ClaimProfitsInput { - // The scheme id. - client.Hash scheme_id = 1; - // The address of beneficiary. - client.Address beneficiary = 2; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/referendum_auth_contract.proto b/AElf.Client/Protobuf/Proto/referendum_auth_contract.proto deleted file mode 100644 index 44b2e9a..0000000 --- a/AElf.Client/Protobuf/Proto/referendum_auth_contract.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; - -import "client.proto"; - -option csharp_namespace = "AElf.Client.ReferendumAuth"; - -message Organization { - // The organization members. - OrganizationMemberList organization_member_list = 1; - // The threshold for releasing the proposal. - client.ProposalReleaseThreshold proposal_release_threshold = 2; - // The proposer whitelist. - client.ProposerWhiteList proposer_white_list = 3; - // The address of organization. - client.Address organization_address = 4; - // The organizations id. - client.Hash organization_hash = 5; - // The creation token is for organization address generation. - client.Hash creation_token = 6; -} - -message OrganizationMemberList { - // The address of organization members. - repeated client.Address organization_members = 1; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/toekn_converter_contract.proto b/AElf.Client/Protobuf/Proto/toekn_converter_contract.proto deleted file mode 100644 index d33a4c5..0000000 --- a/AElf.Client/Protobuf/Proto/toekn_converter_contract.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "AElf.Client.TokenConverter"; - -//token converter -message TokenSymbol { - // The token symbol. - string symbol = 1; -} - -message Connector { - // The token symbol. - string symbol = 1; - // The virtual balance for base token. - int64 virtual_balance = 2; - // The calculated weight value for this Connector. - string weight = 3; - // Whether to use Virtual Balance. - bool is_virtual_balance_enabled = 4; - // Whether the connector is enabled. - bool is_purchase_enabled = 5; - // Indicates its related connector, the pair connector includes a new created token connector and the base token connector. - string related_symbol = 6; - // Indicates if the connector is base token connector. - bool is_deposit_account = 7; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/token_contract.proto b/AElf.Client/Protobuf/Proto/token_contract.proto deleted file mode 100644 index 54070ff..0000000 --- a/AElf.Client/Protobuf/Proto/token_contract.proto +++ /dev/null @@ -1,136 +0,0 @@ -syntax = "proto3"; - -import "client.proto"; - -option csharp_namespace = "AElf.Client.MultiToken"; - -//tokenContract -message TokenInfo { - // The symbol of the token.f - string symbol = 1; - // The full name of the token. - string token_name = 2; - // The current supply of the token. - int64 supply = 3; - // The total supply of the token. - int64 total_supply = 4; - // The precision of the token. - int32 decimals = 5; - // The address that created the token. - client.Address issuer = 6; - // A flag indicating if this token is burnable. - bool is_burnable = 7; - // The chain id of the token. - int32 issue_chain_id = 8; - // The amount of issued tokens. - int64 issued = 9; -} - -message GetTokenInfoInput { - // The symbol of token. - string symbol = 1; -} - -message TokenInfoList { - // List of token information. - repeated TokenInfo value = 1; -} - -message GetBalanceInput { - // The symbol of token. - string symbol = 1; - // The target address of the query. - client.Address owner = 2; -} - -message GetBalanceOutput { - // The symbol of token. - string symbol = 1; - // The target address of the query. - client.Address owner = 2; - // The balance of the owner. - int64 balance = 3; -} - -message GetAllowanceInput { - // The symbol of token. - string symbol = 1; - // The address of the token owner. - client.Address owner = 2; - // The address of the spender. - client.Address spender = 3; -} - -message GetAllowanceOutput { - // The symbol of token. - string symbol = 1; - // The address of the token owner. - client.Address owner = 2; - // The address of the spender. - client.Address spender = 3; - // The amount of allowance. - int64 allowance = 4; -} - -message IsInWhiteListInput { - // The symbol of token. - string symbol = 1; - // The address to check. - client.Address address = 2; -} - -message GetLockedAmountInput { - // The address of the lock. - client.Address address = 1; - // The token symbol. - string symbol = 2; - // The id of the lock. - client.Hash lock_id = 3; -} - -message GetLockedAmountOutput { - // The address of the lock. - client.Address address = 1; - // The token symbol. - string symbol = 2; - // The id of the lock. - client.Hash lock_id = 3; - // The locked amount. - int64 amount = 4; -} - -message GetVirtualAddressForLockingInput { - // The address of the lock. - client.Address address = 1; - // The id of the lock. - client.Hash lock_id = 2; -} - -message GetCrossChainTransferTokenContractAddressInput { - // The chain id. - int32 chainId = 1; -} - -message TransferFromInput { - // The source address of the token. - client.Address from = 1; - // The destination address of the token. - client.Address to = 2; - // The symbol of the token to transfer. - string symbol = 3; - // The amount to transfer. - int64 amount = 4; - // The memo. - string memo = 5; -} - -message TransferInput { - // The receiver of the token. - client.Address to = 1; - // The token symbol to transfer. - string symbol = 2; - // The amount to to transfer. - int64 amount = 3; - // The memo. - string memo = 4; -} diff --git a/AElf.Client/Protobuf/Proto/transaction_fee.proto b/AElf.Client/Protobuf/Proto/transaction_fee.proto deleted file mode 100644 index 9d3080c..0000000 --- a/AElf.Client/Protobuf/Proto/transaction_fee.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto3"; - -package client; - -import "options.proto"; -import "client.proto"; - -option csharp_namespace = "AElf.Client.MultiToken"; - -// Messages - -message TransactionSizeFeeSymbols -{ - repeated TransactionSizeFeeSymbol transaction_size_fee_symbol_list = 1; -} - -message TransactionSizeFeeSymbol -{ - string token_symbol = 1; - sint32 base_token_weight = 2; - sint32 added_token_weight = 3; -} - -// Events - -message TransactionFeeCharged { - option (client.is_event) = true; - string symbol = 1; - sint64 amount = 2; -} - -message ResourceTokenCharged { - option (client.is_event) = true; - string symbol = 1; - sint64 amount = 2; - Address contract_address = 3; -} - -message ResourceTokenOwned { - option (client.is_event) = true; - string symbol = 1; - sint64 amount = 2; - Address contract_address = 3; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/treasury_contract.proto b/AElf.Client/Protobuf/Proto/treasury_contract.proto deleted file mode 100644 index 460d03f..0000000 --- a/AElf.Client/Protobuf/Proto/treasury_contract.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -option csharp_namespace = "AElf.Client.Treasury"; - -//treasury_contract -message GetWelfareRewardAmountSampleInput { - // Token lock time. - repeated int64 value = 1; -} - -message GetWelfareRewardAmountSampleOutput { - // The weight calculated. - repeated int64 value = 1; -} \ No newline at end of file diff --git a/AElf.Client/Protobuf/Proto/vote_contract.proto b/AElf.Client/Protobuf/Proto/vote_contract.proto deleted file mode 100644 index fff3d1c..0000000 --- a/AElf.Client/Protobuf/Proto/vote_contract.proto +++ /dev/null @@ -1,78 +0,0 @@ -syntax = "proto3"; - -import "client.proto"; -import "google/protobuf/timestamp.proto"; - -option csharp_namespace = "AElf.Client.Vote"; - -message GetVotingItemInput { - // The voting activity id. - client.Hash voting_item_id = 1; -} - -message VotedItems { - // The voted ids. - map voted_item_vote_ids = 1; -} - -message VotedIds { - // The active vote ids. - repeated client.Hash active_votes = 1; - // The withdrawn vote ids. - repeated client.Hash withdrawn_votes = 2; -} - -message GetVotingResultInput { - // The voting activity id. - client.Hash voting_item_id = 1; - // The snapshot number. - int64 snapshot_number = 2; -} - -message VotingResult { - // The voting activity id. - client.Hash voting_item_id = 1; - // The voting result, option -> amount of votes, - map results = 2; - // The snapshot number. - int64 snapshot_number = 3; - // The total number of voters. - int64 voters_count = 4; - // The start time of this snapshot. - google.protobuf.Timestamp snapshot_start_timestamp = 5; - // The end time of this snapshot. - google.protobuf.Timestamp snapshot_end_timestamp = 6; - // Total votes received during the process of this snapshot. - int64 votes_amount = 7; -} - -message VotingRecord { - // The voting activity id. - client.Hash voting_item_id = 1; - // The address of voter. - client.Address voter = 2; - // The snapshot number. - int64 snapshot_number = 3; - // The amount of vote. - int64 amount = 4; - // The time of withdraw. - google.protobuf.Timestamp withdraw_timestamp = 5; - // The time of vote. - google.protobuf.Timestamp vote_timestamp = 6; - // Whether the vote had been withdrawn. - bool is_withdrawn = 7; - // The option voted. - string option = 8; - // Whether vote others. - bool is_change_target = 9; -} - -message GetVotingRecordsInput { - // The vote ids. - repeated client.Hash ids = 1; -} - -message VotingRecords { - // The voting records. - repeated VotingRecord records = 1; -} diff --git a/AElf.Client/Service/AElfClient.cs b/AElf.Client/Service/AElfClient.cs deleted file mode 100644 index 92c46fb..0000000 --- a/AElf.Client/Service/AElfClient.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using AElf.Client.Dto; -using AElf.Client.Model; -using AElf.Cryptography; -using AElf.Cryptography.ECDSA; -using AElf.Types; -using Google.Protobuf; -using Google.Protobuf.WellKnownTypes; -using Address = AElf.Types.Address; -using Hash = AElf.Types.Hash; - -namespace AElf.Client.Service -{ - public interface IClientService - { - Task IsConnectedAsync(); - Task GetFormattedAddressAsync(Address address); - Task GetGenesisContractAddressAsync(); - Task
GetContractAddressByNameAsync(Hash contractNameHash); - string GetAddressFromPubKey(string pubKey); - KeyPairInfo GenerateKeyPairInfo(); - } - - public partial class AElfClient : IClientService - { - private readonly IHttpService _httpService; - private string _baseUrl; - private readonly string _userName; - private readonly string _password; - - public string BaseUrl - { - get => _baseUrl; - set => _baseUrl = value; - } - - private const string ExamplePrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; - - public AElfClient(string baseUrl, int timeOut = 60, string userName = null, string password = null) - { - _httpService = new HttpService(timeOut); - _baseUrl = baseUrl; - _userName = userName; - _password = password; - } - - /// - /// Verify whether this sdk successfully connects the chain. - /// - /// IsConnected or not - public async Task IsConnectedAsync() - { - try - { - var chainStatus = await GetChainStatusAsync(); - return chainStatus != null; - } - catch (Exception) - { - return false; - } - } - - /// - /// Get the address of genesis contract. - /// - /// Address - public async Task GetGenesisContractAddressAsync() - { - var statusDto = await GetChainStatusAsync(); - var genesisAddress = statusDto.GenesisContractAddress; - - return genesisAddress; - } - - /// - /// Get address of a contract by given contractNameHash. - /// - /// - /// - /// Address - public async Task
GetContractAddressByNameAsync(Hash contractNameHash) - { - var from = GetAddressFromPrivateKey(ExamplePrivateKey); - var to = await GetGenesisContractAddressAsync(); - var transaction = await GenerateTransactionAsync(from, to, "GetContractAddressByName", contractNameHash); - var txWithSig = SignTransaction(ExamplePrivateKey, transaction); - - var response = await ExecuteTransactionAsync(new ExecuteTransactionDto - { - RawTransaction = txWithSig.ToByteArray().ToHex() - }); - var byteArray = ByteArrayHelper.HexStringToByteArray(response); - var address = Address.Parser.ParseFrom(byteArray); - - return address; - } - - /// - /// Build a transaction from the input parameters. - /// - /// - /// - /// - /// - /// Transaction unsigned - public async Task GenerateTransactionAsync(string from, string to, - string methodName, IMessage input) - { - try - { - AssertValidAddress(from, to); - var chainStatus = await GetChainStatusAsync(); - var transaction = new Transaction - { - From = Address.FromBase58(from), - To = Address.FromBase58(to), - MethodName = methodName, - Params = input.ToByteString(), - RefBlockNumber = chainStatus.BestChainHeight, - RefBlockPrefix = ByteString.CopyFrom(Hash.LoadFromHex(chainStatus.BestChainHash).Value - .Take(4).ToArray()) - }; - - return transaction; - } - catch (Exception) - { - return null; - } - } - - /// - /// Convert the Address to the displayed string:symbol_base58-string_base58-string-chain-id - /// - /// - /// - public async Task GetFormattedAddressAsync(Address address) - { - var tokenContractAddress = await GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); - var fromAddress = GetAddressFromPrivateKey(ExamplePrivateKey); - var toAddress = tokenContractAddress.ToBase58(); - var methodName = "GetPrimaryTokenSymbol"; - var param = new Empty(); - - var transaction = await GenerateTransactionAsync(fromAddress, toAddress, methodName, param); - var txWithSign = SignTransaction(ExamplePrivateKey, transaction); - - var result = await ExecuteTransactionAsync(new ExecuteTransactionDto - { - RawTransaction = txWithSign.ToByteArray().ToHex() - }); - - var symbol = StringValue.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(result)); - var chainIdString = (await GetChainStatusAsync()).ChainId; - - return $"{symbol.Value}_{address.ToBase58()}_{chainIdString}"; - } - - /// - /// Sign a transaction using private key. - /// - /// - /// - /// Transaction signed - public Transaction SignTransaction(string privateKeyHex, Transaction transaction) - { - var transactionData = transaction.GetHash().ToByteArray(); - - // Sign the hash - var privateKey = ByteArrayHelper.HexStringToByteArray(privateKeyHex); - var signature = CryptoHelper.SignWithPrivateKey(privateKey, transactionData); - transaction.Signature = ByteString.CopyFrom(signature); - - return transaction; - } - - /// - /// Get the account address through the public key. - /// - /// - /// Account - public string GetAddressFromPubKey(string pubKey) - { - var publicKey = ByteArrayHelper.HexStringToByteArray(pubKey); - var address = Address.FromPublicKey(publicKey); - return address.ToBase58(); - } - - /// - /// Get the account address through the private key. - /// - /// - /// - public string GetAddressFromPrivateKey(string privateKeyHex) - { - var address = Address.FromPublicKey(GetAElfKeyPair(privateKeyHex).PublicKey); - return address.ToBase58(); - } - - public Address GetBase58String(string base58String) - { - return Address.FromBase58(base58String); - } - - public KeyPairInfo GenerateKeyPairInfo() - { - var keyPair = CryptoHelper.GenerateKeyPair(); - var privateKey = keyPair.PrivateKey.ToHex(); - var publicKey = keyPair.PublicKey.ToHex(); - var address = GetAddressFromPrivateKey(privateKey); - - return new KeyPairInfo - { - PrivateKey = privateKey, - PublicKey = publicKey, - Address = address - }; - } - - #region private methods - - private ECKeyPair GetAElfKeyPair(string privateKeyHex) - { - var privateKey = ByteArrayHelper.HexStringToByteArray(privateKeyHex); - var keyPair = CryptoHelper.FromPrivateKey(privateKey); - - return keyPair; - } - - private string GetRequestUrl(string baseUrl, string relativeUrl) - { - return new Uri(new Uri(baseUrl + (baseUrl.EndsWith("/") ? "" : "/")), relativeUrl).ToString(); - } - - private void AssertValidAddress(params string[] addresses) - { - try - { - foreach (var address in addresses) - { - Types.Address.FromBase58(address); - } - } - catch (Exception) - { - throw new AElfClientException(Error.Message[Error.InvalidAddress]); - } - } - - private void AssertValidHash(params string[] hashes) - { - try - { - foreach (var hash in hashes) - { - Hash.LoadFromHex(hash); - } - } - catch (Exception) - { - throw new AElfClientException(Error.Message[Error.InvalidBlockHash]); - } - } - - private void AssertValidTransactionId(params string[] transactionIds) - { - try - { - foreach (var transactionId in transactionIds) - { - Hash.LoadFromHex(transactionId); - } - } - catch (Exception) - { - throw new AElfClientException(Error.Message[Error.InvalidTransactionId]); - } - } - - #endregion - } -} \ No newline at end of file diff --git a/AElf.Client/Service/BlockAppService.cs b/AElf.Client/Service/BlockAppService.cs deleted file mode 100644 index 2fc5fbb..0000000 --- a/AElf.Client/Service/BlockAppService.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Threading.Tasks; -using AElf.Client.Dto; - -namespace AElf.Client.Service -{ - public interface IBlockAppService - { - Task GetBlockHeightAsync(); - - Task GetBlockByHashAsync(string blockHash, bool includeTransactions = false); - - Task GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false); - } - - public partial class AElfClient : IBlockAppService - { - /// - /// Get height of the current chain. - /// - /// Height - public async Task GetBlockHeightAsync() - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/blockHeight"); - return await _httpService.GetResponseAsync(url); - } - - /// - /// Get information of a block by given block hash. Optional whether to include transaction information. - /// - /// - /// - /// Block information - public async Task GetBlockByHashAsync(string blockHash, bool includeTransactions = false) - { - AssertValidHash(blockHash); - var url = GetRequestUrl(_baseUrl, - $"api/blockChain/block?blockHash={blockHash}&includeTransactions={includeTransactions}"); - return await _httpService.GetResponseAsync(url); - } - - /// - /// Get information of a block by specified height. Optional whether to include transaction information. - /// - /// - /// - /// Block information - public async Task GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false) - { - var url = GetRequestUrl(_baseUrl, - $"api/blockChain/blockByHeight?blockHeight={blockHeight}&includeTransactions={includeTransactions}"); - return await _httpService.GetResponseAsync(url); - } - } -} \ No newline at end of file diff --git a/AElf.Client/Service/ChainAppService.cs b/AElf.Client/Service/ChainAppService.cs deleted file mode 100644 index 79f9d48..0000000 --- a/AElf.Client/Service/ChainAppService.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using AElf.Client.Dto; - -namespace AElf.Client.Service -{ - public interface IChainAppService - { - Task GetChainStatusAsync(); - - Task GetContractFileDescriptorSetAsync(string address); - - Task> GetTaskQueueStatusAsync(); - - Task GetChainIdAsync(); - } - - public partial class AElfClient : IChainAppService - { - /// - /// Get the current status of the block chain. - /// - /// Description of current status - public async Task GetChainStatusAsync() - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/chainStatus"); - return await _httpService.GetResponseAsync(url); - } - - /// - /// Get the definitions of proto-buff related to a contract. - /// - /// - /// Definitions of proto-buff - public async Task GetContractFileDescriptorSetAsync(string address) - { - AssertValidAddress(address); - var url = GetRequestUrl(_baseUrl, $"api/blockChain/contractFileDescriptorSet?address={address}"); - return await _httpService.GetResponseAsync(url); - } - - /// - /// Gets the status information of the task queue. - /// - /// Information of the task queue - public async Task> GetTaskQueueStatusAsync() - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/taskQueueStatus"); - return await _httpService.GetResponseAsync>(url); - } - - /// - /// Get id of the chain. - /// - /// ChainId - public async Task GetChainIdAsync() - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/chainStatus"); - var statusDto = await _httpService.GetResponseAsync(url); - var base58ChainId = statusDto.ChainId; - var chainId = ChainHelper.ConvertBase58ToChainId(base58ChainId); - - return chainId; - } - } -} \ No newline at end of file diff --git a/AElf.Client/Service/HttpService.cs b/AElf.Client/Service/HttpService.cs deleted file mode 100644 index 4cde237..0000000 --- a/AElf.Client/Service/HttpService.cs +++ /dev/null @@ -1,240 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace AElf.Client.Service -{ - public interface IHttpService - { - Task GetResponseAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK); - - Task PostResponseAsync(string url, Dictionary parameters, - string version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null); - - Task DeleteResponseAsObjectAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null); - } - - public class HttpService : IHttpService - { - private HttpClient Client { get; set; } - private int TimeoutSeconds { get; } - - public HttpService(int timeoutSeconds) - { - TimeoutSeconds = timeoutSeconds; - } - - /// - /// Get request. - /// - /// - /// - /// - /// - /// - public async Task GetResponseAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) - { - var response = await GetResponseAsStringAsync(url, version, expectedStatusCode); - return JsonConvert.DeserializeObject(response, new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); - } - - /// - /// Post request. - /// - /// - /// - /// - /// - /// - /// - /// - public async Task PostResponseAsync(string url, Dictionary parameters, - string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null) - { - var response = await PostResponseAsStringAsync(url, parameters, version, expectedStatusCode, - authenticationHeaderValue); - return JsonConvert.DeserializeObject(response, new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); - } - - /// - /// Delete request. - /// - /// - /// - /// - /// - /// - /// - public async Task DeleteResponseAsObjectAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null) - { - var response = - await DeleteResponseAsStringAsync(url, version, expectedStatusCode, authenticationHeaderValue); - return JsonConvert.DeserializeObject(response, new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); - } - - #region GetResponse - - private async Task GetResponseAsStringAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) - { - var response = await GetResponseAsync(url, version, expectedStatusCode); - return await response.Content.ReadAsStringAsync(); - } - - private async Task GetResponseAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) - { - version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; - - var client = GetHttpClient(version); - try - { - var response = await client.GetAsync(url); - if (response.StatusCode == expectedStatusCode) - return response; - throw new AElfClientException(response.ToString()); - } - catch (Exception ex) - { - throw new AElfClientException(ex.Message); - } - } - - #endregion - - #region PostResponse - - private async Task PostResponseAsStringAsync(string url, Dictionary parameters, - string version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null) - { - var response = await PostResponseAsync(url, parameters, version, true, expectedStatusCode, - authenticationHeaderValue); - return await response.Content.ReadAsStringAsync(); - } - - private async Task PostResponseAsync(string url, - Dictionary parameters, - string version = null, bool useApplicationJson = false, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null) - { - version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; - var client = GetHttpClient(version); - - if (authenticationHeaderValue != null) - { - client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; - } - - HttpContent content; - if (useApplicationJson) - { - var paramsStr = JsonConvert.SerializeObject(parameters); - content = new StringContent(paramsStr, Encoding.UTF8, "application/json"); - content.Headers.ContentType = MediaTypeHeaderValue.Parse($"application/json{version}"); - } - - else - { - content = new FormUrlEncodedContent(parameters); - content.Headers.ContentType = - MediaTypeHeaderValue.Parse($"application/x-www-form-urlencoded{version}"); - } - - try - { - var response = await client.PostAsync(url, content); - if (response.StatusCode == expectedStatusCode) - return response; - var message = await response.Content.ReadAsStringAsync(); - throw new HttpRequestException(message); - } - catch (Exception ex) - { - throw new AElfClientException(ex.Message); - } - } - - #endregion - - #region DeleteResponse - - private async Task DeleteResponseAsStringAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null) - { - var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); - return await response.Content.ReadAsStringAsync(); - } - - private async Task DeleteResponseAsync(string url, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null) - { - version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; - var client = GetHttpClient(version); - - if (authenticationHeaderValue != null) - { - client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; - } - - try - { - var response = await client.DeleteAsync(url); - if (response.StatusCode == expectedStatusCode) - return response; - throw new AElfClientException(response.ToString()); - } - catch (Exception ex) - { - throw new AElfClientException(ex.Message); - } - } - - #endregion - - #region private methods - - private HttpClient GetHttpClient(string version = null) - { - if (Client != null) return Client; - Client = new HttpClient - { - Timeout = TimeSpan.FromSeconds(TimeoutSeconds) - }; - Client.DefaultRequestHeaders.Accept.Clear(); - Client.DefaultRequestHeaders.Accept.Add( - MediaTypeWithQualityHeaderValue.Parse($"application/json{version}")); - Client.DefaultRequestHeaders.Add("Connection", "close"); - return Client; - } - - #endregion - } -} \ No newline at end of file diff --git a/AElf.Client/Service/NetAppService.cs b/AElf.Client/Service/NetAppService.cs deleted file mode 100644 index 22a7baa..0000000 --- a/AElf.Client/Service/NetAppService.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; -using AElf.Client.Dto; -using AElf.Client.Helper; - -namespace AElf.Client.Service -{ - public interface INetAppService - { - Task AddPeerAsync(string ipAddress, string userName, string password); - - Task RemovePeerAsync(string ipAddress, string userName, string password); - - Task> GetPeersAsync(bool withMetrics); - - Task GetNetworkInfoAsync(); - } - - public partial class AElfClient : INetAppService - { - /// - /// Attempt to add a node to the connected network nodes.Input parameter contains the ipAddress of the node. - /// - /// - /// - /// - /// Add successfully or not - public async Task AddPeerAsync(string ipAddress, string userName, string password) - { - if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) - { - return false; - } - - var url = GetRequestUrl(_baseUrl, "api/net/peer"); - var parameters = new Dictionary - { - {"address", endpoint.ToString()} - }; - - return await _httpService.PostResponseAsync(url, parameters, - authenticationHeaderValue: GetAuthenticationHeaderValue()); - } - - /// - /// Attempt to remove a node from the connected network nodes by given the ipAddress. - /// - /// - /// - /// - /// Delete successfully or not - public async Task RemovePeerAsync(string ipAddress, string userName, string password) - { - if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) - { - return false; - } - - var url = GetRequestUrl(_baseUrl, $"api/net/peer?address={endpoint}"); - return await _httpService.DeleteResponseAsObjectAsync(url, - authenticationHeaderValue: GetAuthenticationHeaderValue()); - } - - /// - /// Gets information about the peer nodes of the current node.Optional whether to include metrics. - /// - /// - /// Information about the peer nodes - public async Task> GetPeersAsync(bool withMetrics) - { - var url = GetRequestUrl(_baseUrl, $"api/net/peers?withMetrics={withMetrics}"); - return await _httpService.GetResponseAsync>(url); - } - - /// - /// Get the node's network information. - /// - /// Network information - public async Task GetNetworkInfoAsync() - { - var url = GetRequestUrl(_baseUrl, "api/net/networkInfo"); - return await _httpService.GetResponseAsync(url); - } - - private AuthenticationHeaderValue GetAuthenticationHeaderValue() - { - var byteArray = Encoding.ASCII.GetBytes($"{_userName}:{_password}"); - return new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); - } - } -} \ No newline at end of file diff --git a/AElf.Client/Service/TransactionAppService.cs b/AElf.Client/Service/TransactionAppService.cs deleted file mode 100644 index ea8d60e..0000000 --- a/AElf.Client/Service/TransactionAppService.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using AElf.Client.Dto; - -namespace AElf.Client.Service -{ - public interface ITransactionAppService - { - Task GetTransactionPoolStatusAsync(); - - Task ExecuteTransactionAsync(ExecuteTransactionDto input); - - Task ExecuteRawTransactionAsync(ExecuteRawTransactionDto input); - - Task CreateRawTransactionAsync(CreateRawTransactionInput input); - - Task SendRawTransactionAsync(SendRawTransactionInput input); - - Task SendTransactionAsync(SendTransactionInput input); - - Task SendTransactionsAsync(SendTransactionsInput input); - - Task GetTransactionResultAsync(string transactionId); - - Task> GetTransactionResultsAsync(string blockHash, int offset = 0, - int limit = 10); - - Task GetMerklePathByTransactionIdAsync(string transactionId); - } - - public partial class AElfClient : ITransactionAppService - { - /// - /// Get information about the current transaction pool. - /// - /// TransactionPoolStatusOutput - public async Task GetTransactionPoolStatusAsync() - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/transactionPoolStatus"); - return await _httpService.GetResponseAsync(url); - } - - /// - /// Call a read-only method of a contract. - /// - /// - /// - public async Task ExecuteTransactionAsync(ExecuteTransactionDto input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/executeTransaction"); - var parameters = new Dictionary - { - {"RawTransaction", input.RawTransaction} - }; - - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Call a method of a contract by given serialized strings. - /// - /// - /// Serialized result - public async Task ExecuteRawTransactionAsync(ExecuteRawTransactionDto input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/executeRawTransaction"); - var parameters = new Dictionary - { - {"RawTransaction", input.RawTransaction}, - {"Signature", input.Signature} - }; - - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Creates an unsigned serialized transaction. - /// - /// - /// CreateRawTransactionOutput - public async Task CreateRawTransactionAsync(CreateRawTransactionInput input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/rawTransaction"); - var parameters = new Dictionary - { - {"From", input.From}, - {"To", input.To}, - {"RefBlockNumber", input.RefBlockNumber.ToString()}, - {"RefBlockHash", input.RefBlockHash}, - {"MethodName", input.MethodName}, - {"Params", input.Params} - }; - - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Broadcast a serialized transaction. - /// - /// - /// SendRawTransactionOutput - public async Task SendRawTransactionAsync(SendRawTransactionInput input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/sendRawTransaction"); - var parameters = new Dictionary - { - {"Transaction", input.Transaction}, - {"Signature", input.Signature}, - {"ReturnTransaction", input.ReturnTransaction ? "true" : "false"} - }; - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Broadcast a transaction. - /// - /// - /// TransactionId - public async Task SendTransactionAsync(SendTransactionInput input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/sendTransaction"); - var parameters = new Dictionary - { - {"RawTransaction", input.RawTransaction} - }; - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Broadcast volume transactions. - /// - /// - /// TransactionIds - public async Task SendTransactionsAsync(SendTransactionsInput input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/sendTransactions"); - var parameters = new Dictionary - { - {"RawTransactions", input.RawTransactions} - }; - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Gets the result of transaction execution by the given transactionId. - /// - /// - /// TransactionResultDto - public async Task GetTransactionResultAsync(string transactionId) - { - AssertValidTransactionId(transactionId); - var url = GetRequestUrl(_baseUrl, $"api/blockChain/transactionResult?transactionId={transactionId}"); - return await _httpService.GetResponseAsync(url); - } - - /// - /// Get results of multiple transactions by specified blockHash and the offset. - /// - /// - /// - /// - /// TransactionResultDtos - public async Task> GetTransactionResultsAsync(string blockHash, int offset = 0, - int limit = 10) - { - AssertValidHash(blockHash); - var url = GetRequestUrl(_baseUrl, - $"api/blockChain/transactionResults?blockHash={blockHash}&offset={offset}&limit={limit}"); - return await _httpService.GetResponseAsync>(url); - } - - /// - /// Get merkle path of a transaction. - /// - /// - /// MerklePathDto - public async Task GetMerklePathByTransactionIdAsync(string transactionId) - { - AssertValidTransactionId(transactionId); - var url = GetRequestUrl(_baseUrl, $"api/blockChain/merklePathByTransactionId?transactionId={transactionId}"); - return await _httpService.GetResponseAsync(url); - } - } -} \ No newline at end of file diff --git a/all.sln b/all.sln index c212fa2..3e3a5d1 100644 --- a/all.sln +++ b/all.sln @@ -16,6 +16,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ElectionViewer", "examples\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AEDPoSViewer", "examples\AEDPoSViewer\AEDPoSViewer.csproj", "{BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Client.Test", "test\AElf.Client.Test\AElf.Client.Test.csproj", "{4D019C99-8B1C-42B0-8630-F1E3661F414B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Client.Abp", "src\AElf.Client.Abp\AElf.Client.Abp.csproj", "{BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +31,8 @@ Global {CA0B4594-2549-4DB1-9079-EA5FD739C6B6} = {5D1BDC45-D6F1-4359-868B-CB85CEC4ABD8} {E678AABE-AF7B-45F4-B931-CF0D77C5AECA} = {5D1BDC45-D6F1-4359-868B-CB85CEC4ABD8} {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729} = {5D1BDC45-D6F1-4359-868B-CB85CEC4ABD8} + {4D019C99-8B1C-42B0-8630-F1E3661F414B} = {7CD2B508-C765-4720-B430-94E79135797A} + {BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F} = {940361AC-2167-4D30-A4F6-9A543C608196} EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1AE7844D-B4D9-4F5A-9D25-7E551B61138E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -49,5 +55,13 @@ Global {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729}.Debug|Any CPU.Build.0 = Debug|Any CPU {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729}.Release|Any CPU.ActiveCfg = Release|Any CPU {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729}.Release|Any CPU.Build.0 = Release|Any CPU + {4D019C99-8B1C-42B0-8630-F1E3661F414B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D019C99-8B1C-42B0-8630-F1E3661F414B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D019C99-8B1C-42B0-8630-F1E3661F414B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D019C99-8B1C-42B0-8630-F1E3661F414B}.Release|Any CPU.Build.0 = Release|Any CPU + {BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/examples/AEDPoSViewer/AEDPoSViewer.csproj b/examples/AEDPoSViewer/AEDPoSViewer.csproj index 607ed59..a356a80 100644 --- a/examples/AEDPoSViewer/AEDPoSViewer.csproj +++ b/examples/AEDPoSViewer/AEDPoSViewer.csproj @@ -8,9 +8,9 @@ - + - + diff --git a/examples/AEDPoSViewer/AEDPoSViewerModule.cs b/examples/AEDPoSViewer/AEDPoSViewerModule.cs index 2539570..1bd743a 100644 --- a/examples/AEDPoSViewer/AEDPoSViewerModule.cs +++ b/examples/AEDPoSViewer/AEDPoSViewerModule.cs @@ -1,4 +1,4 @@ -using AElf.Client; +using AElf.Client.Abp; using Volo.Abp.Modularity; namespace AEDPoSViewer; diff --git a/examples/AEDPoSViewer/AEDPoSViewerService.cs b/examples/AEDPoSViewer/AEDPoSViewerService.cs index 7dc31b6..65eefa9 100644 --- a/examples/AEDPoSViewer/AEDPoSViewerService.cs +++ b/examples/AEDPoSViewer/AEDPoSViewerService.cs @@ -29,10 +29,10 @@ public async Task RunAsync() var clientService = scope.ServiceProvider.GetRequiredService(); var result = await clientService.ViewSystemAsync(AEDPoSViewerConstants.ConsensusSmartContractName, - "GetCurrentRoundInformation", new Empty(), EndpointType.MainNetMainChain.ToString(), "Ean"); + "GetCurrentRoundInformation", new Empty(), EndpointType.MainNetSidechain.ToString()); var round = new Round(); round.MergeFrom(result); - Logger.LogInformation($"Current round: {round.RoundNumber}"); + Logger.LogInformation($"Current round: {round}"); } } \ No newline at end of file diff --git a/protobuf/aelf/core.proto b/protobuf/aelf/core.proto deleted file mode 100644 index e410996..0000000 --- a/protobuf/aelf/core.proto +++ /dev/null @@ -1,147 +0,0 @@ -syntax = "proto3"; - -package aelf; - -option csharp_namespace = "AElf.Types"; - -message Transaction { - // The address of the sender of the transaction. - Address from = 1; - // The address of the contract when calling a contract. - Address to = 2; - // The height of the referenced block hash. - int64 ref_block_number = 3; - // The first four bytes of the referenced block hash. - bytes ref_block_prefix = 4; - // The name of a method in the smart contract at the To address. - string method_name = 5; - // The parameters to pass to the smart contract method. - bytes params = 6; - // When signing a transaction it’s actually a subset of the fields: from/to and the target method as well as - // the parameter that were given. It also contains the reference block number and prefix. - bytes signature = 10000; -} - -message StatePath { - // The partial path of the state path. - repeated string parts = 1; -} - -message ScopedStatePath { - // The scope address, which will be the contract address. - Address address = 1; - // The path of contract state. - StatePath path = 2; -} - -enum TransactionResultStatus { - // The execution result of the transaction does not exist. - NOT_EXISTED = 0; - // The transaction is in the transaction pool waiting to be packaged. - PENDING = 1; - // Transaction execution failed. - FAILED = 2; - // The transaction was successfully executed and successfully packaged into a block. - MINED = 3; - // When executed in parallel, there are conflicts with other transactions. - CONFLICT = 4; - // The transaction is waiting for validation. - PENDING_VALIDATION = 5; - // Transaction validation failed. - NODE_VALIDATION_FAILED = 6; -} - -message TransactionResult { - // The transaction id. - Hash transaction_id = 1; - // The transaction result status. - TransactionResultStatus status = 2; - // The log events. - repeated LogEvent logs = 3; - // Bloom filter for transaction logs. A transaction log event can be defined in the contract and stored - // in the bloom filter after the transaction is executed. Through this filter, we can quickly search for - // and determine whether a log exists in the transaction result. - bytes bloom = 4; - // The return value of the transaction execution. - bytes return_value = 5; - // The height of the block hat packages the transaction. - int64 block_number = 6; - // The hash of the block hat packages the transaction. - Hash block_hash = 7; - // Failed execution error message. - string error = 10; -} - -message LogEvent { - // The contract address. - Address address = 1; - // The name of the log event. - string name = 2; - // The indexed data, used to calculate bloom. - repeated bytes indexed = 3; - // The non indexed data. - bytes non_indexed = 4; -} - -message SmartContractRegistration { - // The category of contract code(0: C#). - sint32 category = 1; - // The byte array of the contract code. - bytes code = 2; - // The hash of the contract code. - Hash code_hash = 3; - // Whether it is a system contract. - bool is_system_contract = 4; - // The version of the current contract. - int32 version = 5; -} - -message TransactionExecutingStateSet { - // The changed states. - map writes = 1; - // The read states. - map reads = 2; - // The deleted states. - map deletes = 3; -} - -message Address -{ - bytes value = 1; -} - -message Hash -{ - bytes value = 1; -} - -message SInt32Value -{ - sint32 value = 1; -} - -message SInt64Value -{ - sint64 value = 1; -} - -message MerklePath { - // The merkle path nodes. - repeated MerklePathNode merkle_path_nodes = 1; -} - -message MerklePathNode{ - // The node hash. - Hash hash = 1; - // Whether it is a left child node. - bool is_left_child_node = 2; -} - -message BinaryMerkleTree { - // The leaf nodes. - repeated Hash nodes = 1; - // The root node hash. - Hash root = 2; - // The count of leaf node. - int32 leaf_count = 3; -} \ No newline at end of file diff --git a/protobuf/aelf/options.proto b/protobuf/aelf/options.proto deleted file mode 100644 index 34058ba..0000000 --- a/protobuf/aelf/options.proto +++ /dev/null @@ -1,38 +0,0 @@ -syntax = "proto3"; - -package aelf; - -import "google/protobuf/descriptor.proto"; - -option csharp_namespace = "AElf"; - -// All aelf custom options field numbers are like 50yxxx -// where y stands for the custom options type: -// 0 - FileOptions -// 1 - MessageOptions -// 2 - FieldOptions -// 3 - EnumOptions -// 4 - EnumValueOptions -// 5 - ServiceOptions -// 6 - MethodOptions - -extend google.protobuf.FileOptions { - string identity = 500001; -} - -extend google.protobuf.ServiceOptions { - repeated string base = 505001; - string csharp_state = 505030; -} - -extend google.protobuf.MethodOptions { - bool is_view = 506001; -} - -extend google.protobuf.MessageOptions { - bool is_event = 50100; -} - -extend google.protobuf.FieldOptions { - bool is_indexed = 502001; -} diff --git a/src/AElf.Client.Abp/AElf.Client.Abp.csproj b/src/AElf.Client.Abp/AElf.Client.Abp.csproj new file mode 100644 index 0000000..838b587 --- /dev/null +++ b/src/AElf.Client.Abp/AElf.Client.Abp.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/src/AElf.Client/AElfClientModule.cs b/src/AElf.Client.Abp/AElfClientModule.cs similarity index 95% rename from src/AElf.Client/AElfClientModule.cs rename to src/AElf.Client.Abp/AElfClientModule.cs index 7e2fb0a..95cfe53 100644 --- a/src/AElf.Client/AElfClientModule.cs +++ b/src/AElf.Client.Abp/AElfClientModule.cs @@ -4,7 +4,7 @@ using Volo.Abp.Autofac; using Volo.Abp.Modularity; -namespace AElf.Client; +namespace AElf.Client.Abp; [DependsOn( typeof(AbpAutofacModule) diff --git a/src/AElf.Client/AElfClientService.cs b/src/AElf.Client.Abp/AElfClientService.cs similarity index 98% rename from src/AElf.Client/AElfClientService.cs rename to src/AElf.Client.Abp/AElfClientService.cs index 26dc9f6..734cbb7 100644 --- a/src/AElf.Client/AElfClientService.cs +++ b/src/AElf.Client.Abp/AElfClientService.cs @@ -2,7 +2,7 @@ using Google.Protobuf; using Volo.Abp.DependencyInjection; -namespace AElf.Client; +namespace AElf.Client.Abp; public class AElfClientService : IAElfClientService, ITransientDependency { diff --git a/src/AElf.Client.Abp/GlobalUsings.cs b/src/AElf.Client.Abp/GlobalUsings.cs new file mode 100644 index 0000000..e2e7f5c --- /dev/null +++ b/src/AElf.Client.Abp/GlobalUsings.cs @@ -0,0 +1 @@ +global using AElf.Types; \ No newline at end of file diff --git a/src/AElf.Client/IAElfAccountProvider.cs b/src/AElf.Client.Abp/IAElfAccountProvider.cs similarity index 98% rename from src/AElf.Client/IAElfAccountProvider.cs rename to src/AElf.Client.Abp/IAElfAccountProvider.cs index 98c4e34..f3a1809 100644 --- a/src/AElf.Client/IAElfAccountProvider.cs +++ b/src/AElf.Client.Abp/IAElfAccountProvider.cs @@ -1,5 +1,5 @@ +using AElf.Client.Abp.Infrastructure; using AElf.Client.Options; -using AElf.OS.Node.Infrastructure; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; @@ -7,7 +7,7 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.Threading; -namespace AElf.Client; +namespace AElf.Client.Abp; public interface IAElfAccountProvider { diff --git a/src/AElf.Client/IAElfClientProvider.cs b/src/AElf.Client.Abp/IAElfClientProvider.cs similarity index 100% rename from src/AElf.Client/IAElfClientProvider.cs rename to src/AElf.Client.Abp/IAElfClientProvider.cs diff --git a/src/AElf.Client/IAElfClientService.cs b/src/AElf.Client.Abp/IAElfClientService.cs similarity index 100% rename from src/AElf.Client/IAElfClientService.cs rename to src/AElf.Client.Abp/IAElfClientService.cs diff --git a/src/AElf.Client.Abp/Infrastructure/IKeyDirectoryProvider.cs b/src/AElf.Client.Abp/Infrastructure/IKeyDirectoryProvider.cs new file mode 100644 index 0000000..a89a5ee --- /dev/null +++ b/src/AElf.Client.Abp/Infrastructure/IKeyDirectoryProvider.cs @@ -0,0 +1,6 @@ +namespace AElf.Client.Abp.Infrastructure; + +public interface IKeyDirectoryProvider +{ + string GetAppDataPath(); +} \ No newline at end of file diff --git a/src/AElf.Client/Infrastructure/KeyDirectoryProvider.cs b/src/AElf.Client.Abp/Infrastructure/KeyDirectoryProvider.cs similarity index 93% rename from src/AElf.Client/Infrastructure/KeyDirectoryProvider.cs rename to src/AElf.Client.Abp/Infrastructure/KeyDirectoryProvider.cs index 7448188..99dd09b 100644 --- a/src/AElf.Client/Infrastructure/KeyDirectoryProvider.cs +++ b/src/AElf.Client.Abp/Infrastructure/KeyDirectoryProvider.cs @@ -1,6 +1,6 @@ using Volo.Abp.DependencyInjection; -namespace AElf.OS.Node.Infrastructure; +namespace AElf.Client.Abp.Infrastructure; public class KeyDirectoryProvider : IKeyDirectoryProvider, ISingletonDependency { diff --git a/src/AElf.Client/Options/AElfAccountOptions.cs b/src/AElf.Client.Abp/Options/AElfAccountOptions.cs similarity index 100% rename from src/AElf.Client/Options/AElfAccountOptions.cs rename to src/AElf.Client.Abp/Options/AElfAccountOptions.cs diff --git a/src/AElf.Client/Options/AElfClientOptions.cs b/src/AElf.Client.Abp/Options/AElfClientOptions.cs similarity index 100% rename from src/AElf.Client/Options/AElfClientOptions.cs rename to src/AElf.Client.Abp/Options/AElfClientOptions.cs diff --git a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj index 2ea3a9c..94da54f 100644 --- a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj +++ b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj @@ -19,6 +19,9 @@ MSBuild:Compile + + MSBuild:Compile + MSBuild:Compile diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj index e8dc05a..ffb9f1b 100644 --- a/src/AElf.Client/AElf.Client.csproj +++ b/src/AElf.Client/AElf.Client.csproj @@ -4,6 +4,10 @@ net6.0 enable enable + AElf.Client + This is a C# client library, used to communicate with the AElf API. + AElf + true @@ -11,9 +15,8 @@ - - - + + diff --git a/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs b/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs new file mode 100644 index 0000000..886aaaa --- /dev/null +++ b/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs @@ -0,0 +1,37 @@ +using AElf.Client.Dto; +using AElf.Contracts.MultiToken; +using Google.Protobuf; + +namespace AElf.Client.Extensions; + +public static class TransactionResultDtoExtension +{ + public static Dictionary GetTransactionFees(this TransactionResultDto transactionResultDto) + { + var result = new Dictionary(); + + var transactionFeeLogs = + transactionResultDto.Logs?.Where(l => l.Name == nameof(TransactionFeeCharged)).ToList(); + if (transactionFeeLogs != null) + { + foreach (var transactionFee in transactionFeeLogs.Select(transactionFeeLog => + TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) + { + result.Add(transactionFee.Symbol, transactionFee.Amount); + } + } + + var resourceTokenLogs = + transactionResultDto.Logs?.Where(l => l.Name == nameof(ResourceTokenCharged)).ToList(); + if (resourceTokenLogs != null) + { + foreach (var resourceToken in resourceTokenLogs.Select(transactionFeeLog => + ResourceTokenCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) + { + result.Add(resourceToken.Symbol, resourceToken.Amount); + } + } + + return result; + } +} \ No newline at end of file diff --git a/src/AElf.Client/Infrastructure/IKeyDirectoryProvider.cs b/src/AElf.Client/Infrastructure/IKeyDirectoryProvider.cs deleted file mode 100644 index e403192..0000000 --- a/src/AElf.Client/Infrastructure/IKeyDirectoryProvider.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AElf.OS.Node.Infrastructure -{ - public interface IKeyDirectoryProvider - { - string GetAppDataPath(); - } -} \ No newline at end of file diff --git a/src/AElf.Client/TransactionBuilder.cs b/src/AElf.Client/TransactionBuilder.cs index 699586d..beb357f 100644 --- a/src/AElf.Client/TransactionBuilder.cs +++ b/src/AElf.Client/TransactionBuilder.cs @@ -1,6 +1,5 @@ using AElf.Cryptography; using Google.Protobuf; -using Volo.Abp.Threading; namespace AElf.Client; @@ -27,8 +26,8 @@ public TransactionBuilder UsePrivateKey(byte[] privateKey) public TransactionBuilder UseSystemContract(string systemContractName) { - ContractAddress = AsyncHelper.RunSync(async () => - (await _aelfClient.GetContractAddressByNameAsync(HashHelper.ComputeFrom(systemContractName))).ToBase58()); + ContractAddress = _aelfClient.GetContractAddressByNameAsync(HashHelper.ComputeFrom(systemContractName)).Result + .ToBase58(); return this; } @@ -54,8 +53,7 @@ public Transaction Build() { var keyPair = CryptoHelper.FromPrivateKey(PrivateKey); var from = Address.FromPublicKey(keyPair.PublicKey).ToBase58(); - var unsignedTx = AsyncHelper.RunSync(async () => - await _aelfClient.GenerateTransactionAsync(from, ContractAddress, MethodName, Parameter)); + var unsignedTx = _aelfClient.GenerateTransactionAsync(from, ContractAddress, MethodName, Parameter).Result; var signedTx = _aelfClient.SignTransaction(PrivateKey, unsignedTx); return signedTx; } diff --git a/AElf.Client.Test/AElf.Client.Test.csproj b/test/AElf.Client.Test/AElf.Client.Test.csproj similarity index 65% rename from AElf.Client.Test/AElf.Client.Test.csproj rename to test/AElf.Client.Test/AElf.Client.Test.csproj index 116a214..f6a8729 100644 --- a/AElf.Client.Test/AElf.Client.Test.csproj +++ b/test/AElf.Client.Test/AElf.Client.Test.csproj @@ -1,20 +1,20 @@ - netcoreapp3.1 + net6.0 false - - + + - - + + - + diff --git a/test/AElf.Client.Test/ClientTest.cs b/test/AElf.Client.Test/ClientTest.cs new file mode 100644 index 0000000..4127c7f --- /dev/null +++ b/test/AElf.Client.Test/ClientTest.cs @@ -0,0 +1,564 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using AElf.Cryptography; +using AElf.Types; +using AElf.Client.Dto; +using AElf.Client.Extensions; +using AElf.Client.Service; +using AElf.Contracts.MultiToken; +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Shouldly; +using Volo.Abp.Threading; +using Xunit; +using Xunit.Abstractions; +using Address = AElf.Types.Address; +using Hash = AElf.Types.Hash; + +namespace AElf.Client.Test; + +public class ClientTest +{ + private const string BaseUrl = "http://192.168.196.116:8000"; + + private string _genesisAddress; + private string GenesisAddress => GetGenesisContractAddress(); + + // example contract-method-name + private string ContractMethodName => "GetContractAddressByName"; + + // Address and privateKey of a node. + private readonly string _address; + private const string PrivateKey = "cd86ab6347d8e52bbbe8532141fc59ce596268143a308d1d40fedf385528b458"; + + private AElfClient Client { get; } + private readonly ITestOutputHelper _testOutputHelper; + + private const string UserName = "test1"; + private const string Password = "test"; + + public ClientTest(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + Client = new AElfClient(BaseUrl, userName: UserName, password: Password); + + // To get address from privateKey.s + _address = Client.GetAddressFromPrivateKey(PrivateKey); + } + + #region block + + [Fact] + public async Task GetBlockHeightTest() + { + var height = await Client.GetBlockHeightAsync(); + height.ShouldBeGreaterThanOrEqualTo(1); + _testOutputHelper.WriteLine(height.ToString()); + } + + [Fact] + public async Task GetBlock_Test() + { + var height = await Client.GetBlockHeightAsync(); + var blockByHeight = await Client.GetBlockByHeightAsync(height); + var blockByHash = await Client.GetBlockByHashAsync(blockByHeight.BlockHash); + + var blockByHeightSerialized =JsonConvert.SerializeObject(blockByHeight, Formatting.Indented); + var blockByHashSerialized =JsonConvert.SerializeObject(blockByHash, Formatting.Indented); + + blockByHeightSerialized.ShouldBe(blockByHashSerialized); + blockByHeight.Header.Height.ShouldBe(height); + blockByHeight.IsComplete().ShouldBeTrue(); + + var block = JsonConvert.SerializeObject(blockByHeight, Formatting.Indented); + _testOutputHelper.WriteLine(block); + } + + [Fact] + public async Task GetBlockByHeight_Failed_Test() + { + const int timeOut = 60; + var httpService = new HttpService(timeOut); + const int heightNotExist = int.MaxValue; + var errorResponse = await httpService.GetResponseAsync( + $"{BaseUrl}/api/blockChain/blockByHeight?blockHeight={heightNotExist}&includeTransactions=false", + expectedStatusCode: HttpStatusCode.Forbidden); + errorResponse.Error.Code.ShouldBe(Error.NotFound.ToString()); + errorResponse.Error.Message.ShouldBe(Error.Message[Error.NotFound]); + var str = JsonConvert.SerializeObject(errorResponse, Formatting.Indented); + _testOutputHelper.WriteLine(str); + } + + #endregion + + #region chain + + [Fact] + public async Task GetChainStatus_Test() + { + var chainStatusDto = await Client.GetChainStatusAsync(); + + chainStatusDto.Branches.Count.ShouldBeGreaterThanOrEqualTo(1); + chainStatusDto.Branches.First().Key.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.Branches.First().Value.ShouldBeGreaterThanOrEqualTo(1); + chainStatusDto.ChainId.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.BestChainHash.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.BestChainHeight.ShouldBeGreaterThanOrEqualTo(1); + chainStatusDto.GenesisBlockHash.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.GenesisContractAddress.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.LongestChainHash.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.LongestChainHeight.ShouldBeGreaterThanOrEqualTo(1); + chainStatusDto.LastIrreversibleBlockHash.ShouldNotBeNullOrWhiteSpace(); + chainStatusDto.LastIrreversibleBlockHeight.ShouldBeGreaterThanOrEqualTo(1); + + var chainStatus = JsonConvert.SerializeObject(chainStatusDto, Formatting.Indented); + _testOutputHelper.WriteLine(chainStatus); + } + + #endregion + + #region net + + /// + /// Work in multiple nodes.(>=2) + /// + /// + [Fact(Skip = "Redo this later.")] + public async Task AddPeer_Test() + { + // add ipAddress + var addressToAdd = "192.168.199.122:7003"; + + var addSuccess = await Client.AddPeerAsync(addressToAdd, UserName, Password); + addSuccess.ShouldBeTrue(); + _testOutputHelper.WriteLine($"Added ipAddress: {addressToAdd}"); + } + + [Fact(Skip = "Redo this later.")] + public async Task RemovePeer_Test() + { + var peers = await Client.GetPeersAsync(false); + peers.ShouldNotBeEmpty(); + + var peerToRemoveAddress = peers[0].IpAddress; + var removeSuccess = await Client.RemovePeerAsync(peerToRemoveAddress, UserName, Password); + Assert.True(removeSuccess); + _testOutputHelper.WriteLine($"Removed ipAddress: {peerToRemoveAddress}"); + } + + [Fact] + public async Task GetPeers_Test() + { + var peers = await Client.GetPeersAsync(false); + Assert.True(peers != null); + var peersInfo = JsonConvert.SerializeObject(peers, Formatting.Indented); + _testOutputHelper.WriteLine(peersInfo); + } + + [Fact] + public async Task GetNetworkInfo_Test() + { + var netWorkInfo = await Client.GetNetworkInfoAsync(); + Assert.True(netWorkInfo != null); + var info = JsonConvert.SerializeObject(netWorkInfo, Formatting.Indented); + _testOutputHelper.WriteLine(info); + } + + #endregion + + #region transaction + + [Fact] + public async Task GetTaskQueueStatus_Test() + { + var taskQueueStatus = await Client.GetTaskQueueStatusAsync(); + taskQueueStatus.ShouldNotBeEmpty(); + + var queueStatus = JsonConvert.SerializeObject(taskQueueStatus, Formatting.Indented); + _testOutputHelper.WriteLine(queueStatus); + } + + [Fact] + public async Task GetTransactionPoolStatus_Test() + { + var poolStatus = await Client.GetTransactionPoolStatusAsync(); + Assert.True(poolStatus != null); + + var status = JsonConvert.SerializeObject(poolStatus, Formatting.Indented); + _testOutputHelper.WriteLine(status); + } + + [Fact] + public async Task ExecuteTransaction_Test() + { + var toAddress = await Client.GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); + var methodName = "GetNativeTokenInfo"; + var param = new Empty(); + + var transaction = await Client.GenerateTransactionAsync(_address, toAddress.ToBase58(), methodName, param); + var txWithSign = Client.SignTransaction(PrivateKey, transaction); + + var transactionResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto + { + RawTransaction = txWithSign.ToByteArray().ToHex() + }); + Assert.True(transactionResult != null); + + var tokenInfo = TokenInfo.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionResult)); + Assert.True(tokenInfo.Symbol == "ELF"); + } + + [Fact] + public async Task CreateRawTransaction_Test() + { + var address = GenesisAddress; + var status = await Client.GetChainStatusAsync(); + var height = status.BestChainHeight; + var blockHash = status.BestChainHash; + + var createRaw = await Client.CreateRawTransactionAsync(new CreateRawTransactionInput + { + From = _address, + To = address, + MethodName = ContractMethodName, + Params = new JObject + { + ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Token").Value.ToBase64() + }.ToString(), + RefBlockNumber = height, + RefBlockHash = blockHash + }); + + createRaw.RawTransaction.ShouldNotBeEmpty(); + } + + [Fact] + public async Task ExecuteRawTransaction_Test() + { + var address = GenesisAddress; + var status = await Client.GetChainStatusAsync(); + var height = status.BestChainHeight; + var blockHash = status.BestChainHash; + + var createRaw = await Client.CreateRawTransactionAsync(new CreateRawTransactionInput + { + From = _address, + To = address, + MethodName = ContractMethodName, + Params = new JObject + { + ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Consensus").Value.ToBase64() + }.ToString(), + RefBlockNumber = height, + RefBlockHash = blockHash + }); + + var transactionId = HashHelper.ComputeFrom(ByteArrayHelper.HexStringToByteArray(createRaw.RawTransaction)); + var signature = GetSignatureWith(PrivateKey, transactionId.ToByteArray()).ToHex(); + var rawTransactionResult = await Client.ExecuteRawTransactionAsync(new ExecuteRawTransactionDto + { + RawTransaction = createRaw.RawTransaction, + Signature = signature + }); + + rawTransactionResult.ShouldNotBeEmpty(); + var consensusAddress = + (await Client.GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Consensus"))) + .ToBase58(); + + var addressResult = rawTransactionResult.Trim('"'); + _testOutputHelper.WriteLine(rawTransactionResult); + addressResult.ShouldBe(consensusAddress); + } + + [Fact] + public async Task SendRawTransaction_Test() + { + var toAddress = GenesisAddress; + var status = await Client.GetChainStatusAsync(); + var height = status.BestChainHeight; + var blockHash = status.BestChainHash; + + var createRaw = await Client.CreateRawTransactionAsync(new CreateRawTransactionInput + { + From = _address, + To = toAddress, + MethodName = ContractMethodName, + Params = new JObject + { + ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Token").Value.ToBase64() + }.ToString(), + RefBlockNumber = height, + RefBlockHash = blockHash + }); + createRaw.RawTransaction.ShouldNotBeEmpty(); + + var transactionId = HashHelper.ComputeFrom(ByteArrayHelper.HexStringToByteArray(createRaw.RawTransaction)); + var signature = GetSignatureWith(PrivateKey, transactionId.ToByteArray()).ToHex(); + + var rawTransactionResult = await Client.SendRawTransactionAsync(new SendRawTransactionInput + { + Transaction = createRaw.RawTransaction, + Signature = signature, + ReturnTransaction = true + }); + + rawTransactionResult.ShouldNotBeNull(); + rawTransactionResult.Transaction.ShouldNotBeNull(); + rawTransactionResult.TransactionId.ShouldNotBeNullOrWhiteSpace(); + + var result = JsonConvert.SerializeObject(rawTransactionResult, Formatting.Indented); + _testOutputHelper.WriteLine(result); + } + + [Fact] + public async Task SendTransaction_Test() + { + var toAddress = GenesisAddress; + var methodName = ContractMethodName; + var param = HashHelper.ComputeFrom("AElf.ContractNames.Vote"); + + var transaction = await Client.GenerateTransactionAsync(_address, toAddress, methodName, param); + var txWithSign = Client.SignTransaction(PrivateKey, transaction); + + var result = await Client.SendTransactionAsync(new SendTransactionInput + { + RawTransaction = txWithSign.ToByteArray().ToHex() + }); + + result.ShouldNotBeNull(); + result.TransactionId.ShouldNotBeNull(); + _testOutputHelper.WriteLine(result.TransactionId); + } + + [Fact] + public async Task SendTransactions_Test() + { + var toAddress = GenesisAddress; + var methodName = ContractMethodName; + var param1 = HashHelper.ComputeFrom("AElf.ContractNames.Token"); + var param2 = HashHelper.ComputeFrom("AElf.ContractNames.Vote"); + + var parameters = new List {param1, param2}; + var sb = new StringBuilder(); + + foreach (var param in parameters) + { + var tx = await Client.GenerateTransactionAsync(_address, toAddress, methodName, param); + var txWithSign = Client.SignTransaction(PrivateKey, tx); + sb.Append(txWithSign.ToByteArray().ToHex() + ','); + } + + var result1 = await Client.SendTransactionsAsync(new SendTransactionsInput + { + RawTransactions = sb.ToString().Substring(0, sb.Length - 1) + }); + + Assert.True(result1 != null); + result1.Length.ShouldBe(2); + _testOutputHelper.WriteLine(JsonConvert.SerializeObject(result1)); + + } + + [Fact] + public async Task GetTransactionResult_Test() + { + var firstBlockDto = await Client.GetBlockByHeightAsync(1, true); + var transactionId = firstBlockDto.Body.Transactions.FirstOrDefault(); + + var transactionResultDto = await Client.GetTransactionResultAsync(transactionId); + Assert.True(transactionResultDto.Status == TransactionResultStatus.Mined.ToString().ToUpper()); + } + + [Fact] + public async Task GetTransactionResults_Test() + { + var firstBlockDto = await Client.GetBlockByHeightAsync(1, true); + var blockHash = firstBlockDto.BlockHash; + + var transactionResults = await Client.GetTransactionResultsAsync(blockHash, 0, 2); + foreach (var transaction in transactionResults) + { + Assert.True(transaction.Status == TransactionResultStatus.Mined.ToString().ToUpper()); + } + } + + [Fact] + public async Task GetMerklePathByTransactionId_Test() + { + var firstBlockDto = await Client.GetBlockByHeightAsync(1, true); + var transactionId = firstBlockDto.Body.Transactions.FirstOrDefault(); + var merklePathDto = await Client.GetMerklePathByTransactionIdAsync(transactionId); + Assert.True(merklePathDto != null); + + var merklePath = JsonConvert.SerializeObject(merklePathDto, Formatting.Indented); + merklePath.ShouldNotBeEmpty(); + + _testOutputHelper.WriteLine(merklePath); + } + + [Fact] + public async Task GetChainId_Test() + { + var chainId = await Client.GetChainIdAsync(); + chainId.ShouldBe(9992731); + } + + [Fact] + public async Task IsConnected_Test() + { + var isConnected = await Client.IsConnectedAsync(); + isConnected.ShouldBeTrue(); + } + + [Fact] + public async Task GetGenesisContractAddress_Test() + { + var genesisAddress = await Client.GetGenesisContractAddressAsync(); + genesisAddress.ShouldNotBeEmpty(); + + var address = await Client.GetContractAddressByNameAsync(Hash.Empty); + var genesisAddress2 = address.ToBase58(); + Assert.True(genesisAddress == genesisAddress2); + } + + [Fact] + public async Task GetFormattedAddress_Test() + { + var result = await Client.GetFormattedAddressAsync(Address.FromBase58(_address)); + _testOutputHelper.WriteLine(result); + Assert.True(result == $"ELF_{_address}_AELF"); + } + + [Fact] + public void GetNewKeyPairInfo_Test() + { + var output = Client.GenerateKeyPairInfo(); + var addressOutput = JsonConvert.SerializeObject(output); + _testOutputHelper.WriteLine(addressOutput); + } + + [Fact] + public async Task Transfer_Test() + { + var toAccount = Client.GenerateKeyPairInfo().Address; + var toAddress = await Client.GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); + var methodName = "Transfer"; + var param = new TransferInput + { + To = new Address {Value = Address.FromBase58(toAccount).Value}, + Symbol = "ELF", + Amount = 1000 + }; + + var transaction = await Client.GenerateTransactionAsync(_address, toAddress.ToBase58(), methodName, param); + var txWithSign = Client.SignTransaction(PrivateKey, transaction); + + var result = await Client.SendTransactionAsync(new SendTransactionInput + { + RawTransaction = txWithSign.ToByteArray().ToHex() + }); + + result.ShouldNotBeNull(); + _testOutputHelper.WriteLine(result.TransactionId); + + await Task.Delay(4000); + var transactionResult = await Client.GetTransactionResultAsync(result.TransactionId); + transactionResult.Status.ShouldBe(TransactionResultStatus.Mined.ToString().ToUpper()); + var transactionFees = transactionResult.GetTransactionFees(); + transactionFees.First().Key.ShouldBe("ELF"); + transactionFees.First().Value.ShouldBeGreaterThan(0L); + _testOutputHelper.WriteLine(JsonConvert.SerializeObject(transactionFees, Formatting.Indented)); + + var paramGetBalance = new GetBalanceInput + { + Symbol = "ELF", + Owner = new Address {Value = Address.FromBase58(toAccount).Value} + }; + + var transactionGetBalance = + await Client.GenerateTransactionAsync(_address, toAddress.ToBase58(), "GetBalance", paramGetBalance); + var txWithSignGetBalance = Client.SignTransaction(PrivateKey, transactionGetBalance); + + var transactionGetBalanceResult = await Client.ExecuteTransactionAsync(new ExecuteTransactionDto + { + RawTransaction = txWithSignGetBalance.ToByteArray().ToHex() + }); + Assert.True(transactionResult != null); + + var balance = + GetBalanceOutput.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionGetBalanceResult)); + balance.Balance.ShouldBe(1000L); + } + + [Fact] + public void GetTransactionFee_Test() + { + var transactionResultDto = new TransactionResultDto + { + Logs = new[] + { + new LogEventDto + { + Name = "TransactionFeeCharged", + NonIndexed = Convert.ToBase64String((new TransactionFeeCharged {Symbol = "ELF", Amount = 1000}).ToByteArray()) + }, + new LogEventDto + { + Name = "ResourceTokenCharged", + NonIndexed = Convert.ToBase64String((new ResourceTokenCharged {Symbol = "READ", Amount = 800}).ToByteArray()) + }, + new LogEventDto + { + Name = "ResourceTokenCharged", + NonIndexed = Convert.ToBase64String((new ResourceTokenCharged {Symbol = "WRITE", Amount = 600}).ToByteArray()) + }, + new LogEventDto + { + Name = "ResourceTokenOwned", + NonIndexed = Convert.ToBase64String((new ResourceTokenOwned {Symbol = "READ", Amount = 200}).ToByteArray()) + } + } + }; + + var transactionFees = transactionResultDto.GetTransactionFees(); + transactionFees.Count.ShouldBe(3); + transactionFees["ELF"].ShouldBe(1000); + transactionFees["READ"].ShouldBe(800); + transactionFees["WRITE"].ShouldBe(600); + + + transactionResultDto = new TransactionResultDto(); + transactionFees = transactionResultDto.GetTransactionFees(); + transactionFees.Count.ShouldBe(0); + } + + #endregion + + #region private methods + + private string GetGenesisContractAddress() + { + if (_genesisAddress != null) return _genesisAddress; + + var statusDto = AsyncHelper.RunSync(Client.GetChainStatusAsync); + _genesisAddress = statusDto.GenesisContractAddress; + + return _genesisAddress; + } + + private ByteString GetSignatureWith(string privateKey, byte[] txData) + { + // Sign the hash + var signature = CryptoHelper.SignWithPrivateKey(ByteArrayHelper.HexStringToByteArray(privateKey), txData); + return ByteString.CopyFrom(signature); + } + + #endregion +} \ No newline at end of file diff --git a/AElf.Client.Test/Extensions.cs b/test/AElf.Client.Test/Extensions.cs similarity index 100% rename from AElf.Client.Test/Extensions.cs rename to test/AElf.Client.Test/Extensions.cs diff --git a/AElf.Client.Test/WebAppErrorResponse.cs b/test/AElf.Client.Test/WebAppErrorResponse.cs similarity index 100% rename from AElf.Client.Test/WebAppErrorResponse.cs rename to test/AElf.Client.Test/WebAppErrorResponse.cs From d5425e2dfc09fd227b5799dbad87fd05f4902ce8 Mon Sep 17 00:00:00 2001 From: yiqi Date: Thu, 2 Jun 2022 17:19:58 +0800 Subject: [PATCH 44/70] Tune csproject file. --- examples/AEDPoSViewer/AEDPoSViewerService.cs | 2 +- src/AElf.Client.Abp/AElf.Client.Abp.csproj | 4 ++++ src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/AEDPoSViewer/AEDPoSViewerService.cs b/examples/AEDPoSViewer/AEDPoSViewerService.cs index 65eefa9..6dafa91 100644 --- a/examples/AEDPoSViewer/AEDPoSViewerService.cs +++ b/examples/AEDPoSViewer/AEDPoSViewerService.cs @@ -29,7 +29,7 @@ public async Task RunAsync() var clientService = scope.ServiceProvider.GetRequiredService(); var result = await clientService.ViewSystemAsync(AEDPoSViewerConstants.ConsensusSmartContractName, - "GetCurrentRoundInformation", new Empty(), EndpointType.MainNetSidechain.ToString()); + "GetCurrentRoundInformation", new Empty(), EndpointType.MainNetSidechain.ToString(), "Ean"); var round = new Round(); round.MergeFrom(result); diff --git a/src/AElf.Client.Abp/AElf.Client.Abp.csproj b/src/AElf.Client.Abp/AElf.Client.Abp.csproj index 838b587..2f6815f 100644 --- a/src/AElf.Client.Abp/AElf.Client.Abp.csproj +++ b/src/AElf.Client.Abp/AElf.Client.Abp.csproj @@ -4,6 +4,10 @@ net6.0 enable enable + AElf.Client.Abp + C# sdk with abp module. + AElf + true diff --git a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj index 94da54f..a582f80 100644 --- a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj +++ b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj @@ -4,6 +4,10 @@ net6.0 enable enable + AElf.Client.Protobuf + Protobuf using by AElf C# sdk. + AElf + true From a142b8713f48fd8e93f8b55c7025ba62068a6063 Mon Sep 17 00:00:00 2001 From: wangyue Date: Fri, 10 Feb 2023 17:58:01 +0800 Subject: [PATCH 45/70] add TransactionFee interface and add UT --- src/AElf.Client/AElfClient.Transaction.cs | 10 +++++ .../Dto/CalculateTransactionFeeInput.cs | 6 +++ .../Dto/TransactionFeeResultOutput.cs | 11 ++++++ .../Services/ITransactionAppService.cs | 2 + test/AElf.Client.Test/ClientTest.cs | 38 ++++++++++++++++++- 5 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 src/AElf.Client/Dto/CalculateTransactionFeeInput.cs create mode 100644 src/AElf.Client/Dto/TransactionFeeResultOutput.cs diff --git a/src/AElf.Client/AElfClient.Transaction.cs b/src/AElf.Client/AElfClient.Transaction.cs index d1b6b4a..da9e9e4 100644 --- a/src/AElf.Client/AElfClient.Transaction.cs +++ b/src/AElf.Client/AElfClient.Transaction.cs @@ -162,4 +162,14 @@ public async Task ExecuteTransactionAsync(ExecuteTransactionDto input) var url = GetRequestUrl(_baseUrl, $"api/blockChain/merklePathByTransactionId?transactionId={transactionId}"); return await _httpService.GetResponseAsync(url); } + + public async Task GetTransactionFeeResultAsync(CalculateTransactionFeeInput input) + { + var url = GetRequestUrl(_baseUrl, "/api/blockChain/calculateTransactionFee"); + var parameters = new Dictionary + { + {"RawTransaction", input.RawTransaction} + }; + return await _httpService.PostResponseAsync(url,parameters); + } } \ No newline at end of file diff --git a/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs b/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs new file mode 100644 index 0000000..248f4c1 --- /dev/null +++ b/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs @@ -0,0 +1,6 @@ +namespace AElf.Client.Dto; + +public class CalculateTransactionFeeInput +{ + public string RawTransaction { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Dto/TransactionFeeResultOutput.cs b/src/AElf.Client/Dto/TransactionFeeResultOutput.cs new file mode 100644 index 0000000..d415adc --- /dev/null +++ b/src/AElf.Client/Dto/TransactionFeeResultOutput.cs @@ -0,0 +1,11 @@ +namespace AElf.Client.Dto; + +public class TransactionFeeResultOutput +{ + + public bool Success { get; set; } + + public Dictionary TransactionFee { get; set; } + + public Dictionary ResourceFee { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Client/Services/ITransactionAppService.cs b/src/AElf.Client/Services/ITransactionAppService.cs index 2bf140a..1bc3a6d 100644 --- a/src/AElf.Client/Services/ITransactionAppService.cs +++ b/src/AElf.Client/Services/ITransactionAppService.cs @@ -24,4 +24,6 @@ public interface ITransactionAppService int limit = 10); Task GetMerklePathByTransactionIdAsync(string transactionId); + + Task GetTransactionFeeResultAsync(CalculateTransactionFeeInput input); } \ No newline at end of file diff --git a/test/AElf.Client.Test/ClientTest.cs b/test/AElf.Client.Test/ClientTest.cs index 4127c7f..a68bd57 100644 --- a/test/AElf.Client.Test/ClientTest.cs +++ b/test/AElf.Client.Test/ClientTest.cs @@ -25,7 +25,7 @@ namespace AElf.Client.Test; public class ClientTest { - private const string BaseUrl = "http://192.168.196.116:8000"; + private const string BaseUrl = "http://127.0.0.1:8000"; private string _genesisAddress; private string GenesisAddress => GetGenesisContractAddress(); @@ -35,7 +35,7 @@ public class ClientTest // Address and privateKey of a node. private readonly string _address; - private const string PrivateKey = "cd86ab6347d8e52bbbe8532141fc59ce596268143a308d1d40fedf385528b458"; + private const string PrivateKey = "4980f789235c786462b24ef23849e90bb1b6d590402a130313ce88d79a6ca3da"; private AElfClient Client { get; } private readonly ITestOutputHelper _testOutputHelper; @@ -537,6 +537,40 @@ public void GetTransactionFee_Test() transactionResultDto = new TransactionResultDto(); transactionFees = transactionResultDto.GetTransactionFees(); transactionFees.Count.ShouldBe(0); + } + + [Fact] + public async void GetTransactionFeeResult_Test() + { + var address = GenesisAddress; + var status = await Client.GetChainStatusAsync(); + var height = status.BestChainHeight; + var blockHash = status.BestChainHash; + + var createRaw = await Client.CreateRawTransactionAsync(new CreateRawTransactionInput + { + From = _address, + To = address, + MethodName = ContractMethodName, + Params = new JObject + { + ["value"] = HashHelper.ComputeFrom("AElf.ContractNames.Token").Value.ToBase64() + }.ToString(), + RefBlockNumber = height, + RefBlockHash = blockHash + }); + + createRaw.RawTransaction.ShouldNotBeEmpty(); + var input = new CalculateTransactionFeeInput + { + RawTransaction = createRaw.RawTransaction + }; + var transactionFeeOutput = await Client.GetTransactionFeeResultAsync(input); + transactionFeeOutput.Success.ShouldBe(true); + + + + } #endregion From dd81977436ff75ed2151d5e3a2c640c898a2d2de Mon Sep 17 00:00:00 2001 From: wangyue Date: Fri, 10 Feb 2023 18:01:28 +0800 Subject: [PATCH 46/70] add new field --- src/AElf.Client/Dto/PeerDto.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AElf.Client/Dto/PeerDto.cs b/src/AElf.Client/Dto/PeerDto.cs index 411c2df..69e4149 100644 --- a/src/AElf.Client/Dto/PeerDto.cs +++ b/src/AElf.Client/Dto/PeerDto.cs @@ -11,6 +11,7 @@ public class PeerDto public int BufferedBlocksCount { get; set; } public int BufferedAnnouncementsCount { get; set; } public List RequestMetrics { get; set; } + public string NodeVersion { get; set; } } public class RequestMetric From e94122edc7c1fbb49b436544dba136307ded62d7 Mon Sep 17 00:00:00 2001 From: wangyue Date: Thu, 16 Feb 2023 14:04:08 +0800 Subject: [PATCH 47/70] update base URL --- test/AElf.Client.Test/ClientTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/AElf.Client.Test/ClientTest.cs b/test/AElf.Client.Test/ClientTest.cs index a68bd57..ce72c9d 100644 --- a/test/AElf.Client.Test/ClientTest.cs +++ b/test/AElf.Client.Test/ClientTest.cs @@ -25,7 +25,7 @@ namespace AElf.Client.Test; public class ClientTest { - private const string BaseUrl = "http://127.0.0.1:8000"; + private const string BaseUrl = "http://192.168.196.116:8000"; private string _genesisAddress; private string GenesisAddress => GetGenesisContractAddress(); @@ -35,7 +35,7 @@ public class ClientTest // Address and privateKey of a node. private readonly string _address; - private const string PrivateKey = "4980f789235c786462b24ef23849e90bb1b6d590402a130313ce88d79a6ca3da"; + private const string PrivateKey = "cd86ab6347d8e52bbbe8532141fc59ce596268143a308d1d40fedf385528b458"; private AElfClient Client { get; } private readonly ITestOutputHelper _testOutputHelper; @@ -540,7 +540,7 @@ public void GetTransactionFee_Test() } [Fact] - public async void GetTransactionFeeResult_Test() + public async void CalculateTransactionFeeResult_Test() { var address = GenesisAddress; var status = await Client.GetChainStatusAsync(); From afcf16651730a02444e9239691c3905ea38c4a0e Mon Sep 17 00:00:00 2001 From: wangyue Date: Fri, 17 Feb 2023 16:51:34 +0800 Subject: [PATCH 48/70] update file --- azure-pipelines.yml | 8 ++++---- scripts/aelf-node/start-mac.sh | 2 +- scripts/aelf-node/start-window.ps1 | 2 +- scripts/aelf-node/start.sh | 4 ++-- test/AElf.Client.Test/ClientTest.cs | 4 +++- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 464e1d0..5038b5c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ jobs: - task: UseDotNet@2 displayName: 'Install .NET Core SDK' inputs: - version: 3.1.101 + version: '6.0.x' - powershell: ./scripts/aelf-node/start-window.ps1 displayName: 'Build and Test' # All tasks on Linux @@ -23,9 +23,9 @@ jobs: pool: vmImage: ubuntu-18.04 steps: - - task: DotNetCoreInstaller@0 + - task: UseDotNet@2 inputs: - version: '3.1.101' + version: '6.0.x' - script: cd scripts/aelf-node && bash start.sh displayName: 'Deploy a full node' - script: bash build.sh -target=test @@ -40,7 +40,7 @@ jobs: steps: - task: DotNetCoreInstaller@0 inputs: - version: '3.1.101' + version: '6.0.x' - script: cd scripts/aelf-node && bash start-mac.sh displayName: 'Deploy a full node' - script: bash build.sh -target=test diff --git a/scripts/aelf-node/start-mac.sh b/scripts/aelf-node/start-mac.sh index e580f84..7d6d2b1 100644 --- a/scripts/aelf-node/start-mac.sh +++ b/scripts/aelf-node/start-mac.sh @@ -3,7 +3,7 @@ brew services start redis brew install unzip mkdir -p ~/.local/share/aelf/keys cd ../../ -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0/aelf.zip && unzip aelf.zip +wget https://github.com/AElfProject/AElf/releases/download/v1.2.3/aelf.zip && unzip aelf.zip cp scripts/aelf-node/keys/SD6BXDrKT2syNd1WehtPyRo3dPBiXqfGUj8UJym7YP9W9RynM.json ~/.local/share/aelf/keys/ cp scripts/aelf-node/app* aelf/ echo "start node" diff --git a/scripts/aelf-node/start-window.ps1 b/scripts/aelf-node/start-window.ps1 index c708a48..7397a99 100644 --- a/scripts/aelf-node/start-window.ps1 +++ b/scripts/aelf-node/start-window.ps1 @@ -4,7 +4,7 @@ $job1 = Start-Job -ScriptBlock { cd D:\a\1\s\redis; .\redis-server.exe; } sleep 30 mkdir -p C:\Users\VssAdministrator\AppData\Local\aelf\keys cp -r scripts\aelf-node\keys\* C:\Users\VssAdministrator\AppData\Local\aelf\keys; -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0/aelf.zip -OutFile aelf.zip ; +wget https://github.com/AElfProject/AElf/releases/download/v1.2.3/aelf.zip -OutFile aelf.zip ; Expand-Archive -Path aelf.zip -DestinationPath aelf ; cp scripts\aelf-node\appsettings.json aelf\aelf\appsettings.json ; cp scripts\aelf-node\appsettings.MainChain.TestNet.json aelf\aelf\appsettings.MainChain.TestNet.json ; diff --git a/scripts/aelf-node/start.sh b/scripts/aelf-node/start.sh index 138b5c5..77cb372 100644 --- a/scripts/aelf-node/start.sh +++ b/scripts/aelf-node/start.sh @@ -3,14 +3,14 @@ ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` sudo apt update && apt install unzip sudo mkdir -p /home/ubuntu/.ssh/aelf/keys && sudo mkdir -p /root/.ssh/aelf/keys cd ../../ -wget https://github.com/AElfProject/AElf/releases/download/v1.0.0/aelf.zip +wget https://github.com/AElfProject/AElf/releases/download/v1.2.3/aelf.zip sudo unzip aelf.zip sed -i "s/127.0.0.1/$ip/g" scripts/aelf-node/appsettings.json sudo mkdir -p aelf/aelf/keys sudo cp scripts/aelf-node/keys/*.json aelf/aelf/keys/ sudo cp scripts/aelf-node/app* aelf/ echo "start node" -cd aelf && sudo dotnet AElf.Launcher.dll >/dev/null 2>&1 & +cd aelf && sudo dotnet AElf.Launcher.dll sleep 30 height=`curl -s http://$ip:8001/api/blockChain/blockHeight` echo "height is $height" diff --git a/test/AElf.Client.Test/ClientTest.cs b/test/AElf.Client.Test/ClientTest.cs index ce72c9d..04d7f23 100644 --- a/test/AElf.Client.Test/ClientTest.cs +++ b/test/AElf.Client.Test/ClientTest.cs @@ -25,7 +25,7 @@ namespace AElf.Client.Test; public class ClientTest { - private const string BaseUrl = "http://192.168.196.116:8000"; + private const string BaseUrl = "http://127.0.0.1:8000"; private string _genesisAddress; private string GenesisAddress => GetGenesisContractAddress(); @@ -567,6 +567,8 @@ public async void CalculateTransactionFeeResult_Test() }; var transactionFeeOutput = await Client.GetTransactionFeeResultAsync(input); transactionFeeOutput.Success.ShouldBe(true); + transactionFeeOutput.TransactionFee["ELF"].ShouldBeGreaterThan(18000000); + transactionFeeOutput.TransactionFee["ELF"].ShouldBeLessThanOrEqualTo(19000000); From fe314fa9d9d66a08fa542bab67134112f1754fe6 Mon Sep 17 00:00:00 2001 From: wangyue Date: Fri, 17 Feb 2023 18:10:21 +0800 Subject: [PATCH 49/70] update setting --- azure-pipelines.yml | 4 ++-- build.config | 2 +- scripts/aelf-node/start.sh | 22 +++++++++++++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5038b5c..3bf6034 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -21,7 +21,7 @@ jobs: ports: - 6379:6379 pool: - vmImage: ubuntu-18.04 + vmImage: ubuntu-latest steps: - task: UseDotNet@2 inputs: @@ -38,7 +38,7 @@ jobs: variables: phpVersion: 7.2 steps: - - task: DotNetCoreInstaller@0 + - task: UseDotNet@2 inputs: version: '6.0.x' - script: cd scripts/aelf-node && bash start-mac.sh diff --git a/build.config b/build.config index 803c029..703c767 100644 --- a/build.config +++ b/build.config @@ -1,3 +1,3 @@ #!/usr/bin/env bash CAKE_VERSION=0.37.0 -DOTNET_VERSION=3.1.101 +DOTNET_VERSION=6.0.406 diff --git a/scripts/aelf-node/start.sh b/scripts/aelf-node/start.sh index 77cb372..f3ae8ed 100644 --- a/scripts/aelf-node/start.sh +++ b/scripts/aelf-node/start.sh @@ -10,7 +10,27 @@ sudo mkdir -p aelf/aelf/keys sudo cp scripts/aelf-node/keys/*.json aelf/aelf/keys/ sudo cp scripts/aelf-node/app* aelf/ echo "start node" -cd aelf && sudo dotnet AElf.Launcher.dll +cd aelf && sudo dotnet AElf.Launcher.dll >/dev/null 2>&1 & sleep 30 height=`curl -s http://$ip:8001/api/blockChain/blockHeight` echo "height is $height" + + + +#!/bin/bash +dir=`pwd` +ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` +sudo sed -i "s/127.0.0.1/$ip/g" appsettings.json +sudo apt update && apt install unzip +sudo mkdir -p /home/ubuntu/.ssh/aelf/keys && sudo mkdir -p /root/.ssh/aelf/keys +cd ../../ +wget https://github.com/AElfProject/AElf/releases/download/v1.2.3/aelf.zip +sudo unzip aelf.zip +sudo mkdir -p aelf/aelf/keys +sudo cp scripts/aelf-node/keys/*.json aelf/aelf/keys/ +sudo cp scripts/aelf-node/app* aelf/ +echo "start node" +cd aelf && sudo dotnet AElf.Launcher.dll >/dev/null 2>&1 & +sleep 30 +height=`curl -s http://$ip:8000/api/blockChain/blockHeight` +echo "height is $height" From d93d20b222672374c945d3fa63b0b5b3f6d60806 Mon Sep 17 00:00:00 2001 From: wangyue Date: Fri, 17 Feb 2023 18:38:36 +0800 Subject: [PATCH 50/70] add log --- scripts/aelf-node/start.sh | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/scripts/aelf-node/start.sh b/scripts/aelf-node/start.sh index f3ae8ed..d00e82f 100644 --- a/scripts/aelf-node/start.sh +++ b/scripts/aelf-node/start.sh @@ -14,23 +14,3 @@ cd aelf && sudo dotnet AElf.Launcher.dll >/dev/null 2>&1 & sleep 30 height=`curl -s http://$ip:8001/api/blockChain/blockHeight` echo "height is $height" - - - -#!/bin/bash -dir=`pwd` -ip=`ip a | grep eth0 |grep 'inet' | awk -F/ '{print $1}'| awk '{print $2}'` -sudo sed -i "s/127.0.0.1/$ip/g" appsettings.json -sudo apt update && apt install unzip -sudo mkdir -p /home/ubuntu/.ssh/aelf/keys && sudo mkdir -p /root/.ssh/aelf/keys -cd ../../ -wget https://github.com/AElfProject/AElf/releases/download/v1.2.3/aelf.zip -sudo unzip aelf.zip -sudo mkdir -p aelf/aelf/keys -sudo cp scripts/aelf-node/keys/*.json aelf/aelf/keys/ -sudo cp scripts/aelf-node/app* aelf/ -echo "start node" -cd aelf && sudo dotnet AElf.Launcher.dll >/dev/null 2>&1 & -sleep 30 -height=`curl -s http://$ip:8000/api/blockChain/blockHeight` -echo "height is $height" From 89054881346f0b51af57ae9d2f2d046cd49163ee Mon Sep 17 00:00:00 2001 From: wangyue Date: Fri, 17 Feb 2023 19:44:02 +0800 Subject: [PATCH 51/70] update build.cake --- build.cake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.cake b/build.cake index 3f1db00..7c3ec95 100755 --- a/build.cake +++ b/build.cake @@ -3,7 +3,7 @@ var rootPath = "./"; var srcPath = rootPath + "AElf.Client/"; var testPath = rootPath + "AElf.Client.Test/"; var distPath = rootPath + "aelf-node/"; -var solution = rootPath + "AElf.Client.sln"; +var solution = rootPath + "All.sln"; var srcProjects = GetFiles(srcPath + "AElf.Client.csproj"); Task("clean") From 8b4940bb23557ed7efd243f44bb7fd70ba3a4d4b Mon Sep 17 00:00:00 2001 From: wangyue Date: Fri, 17 Feb 2023 19:57:40 +0800 Subject: [PATCH 52/70] update build.cake1 --- build.cake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.cake b/build.cake index 7c3ec95..cca8919 100755 --- a/build.cake +++ b/build.cake @@ -3,7 +3,7 @@ var rootPath = "./"; var srcPath = rootPath + "AElf.Client/"; var testPath = rootPath + "AElf.Client.Test/"; var distPath = rootPath + "aelf-node/"; -var solution = rootPath + "All.sln"; +var solution = rootPath + "all.sln"; var srcProjects = GetFiles(srcPath + "AElf.Client.csproj"); Task("clean") From c8a6bd0e47bc49aa5a859e06c8ce0c5be850b04e Mon Sep 17 00:00:00 2001 From: wangyue Date: Mon, 6 Mar 2023 20:17:41 +0800 Subject: [PATCH 53/70] udpate func name and add Assert --- src/AElf.Client/AElfClient.Transaction.cs | 2 +- src/AElf.Client/Services/ITransactionAppService.cs | 2 +- test/AElf.Client.Test/ClientTest.cs | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/AElf.Client/AElfClient.Transaction.cs b/src/AElf.Client/AElfClient.Transaction.cs index da9e9e4..f8993af 100644 --- a/src/AElf.Client/AElfClient.Transaction.cs +++ b/src/AElf.Client/AElfClient.Transaction.cs @@ -163,7 +163,7 @@ public async Task ExecuteTransactionAsync(ExecuteTransactionDto input) return await _httpService.GetResponseAsync(url); } - public async Task GetTransactionFeeResultAsync(CalculateTransactionFeeInput input) + public async Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input) { var url = GetRequestUrl(_baseUrl, "/api/blockChain/calculateTransactionFee"); var parameters = new Dictionary diff --git a/src/AElf.Client/Services/ITransactionAppService.cs b/src/AElf.Client/Services/ITransactionAppService.cs index 1bc3a6d..43cb338 100644 --- a/src/AElf.Client/Services/ITransactionAppService.cs +++ b/src/AElf.Client/Services/ITransactionAppService.cs @@ -25,5 +25,5 @@ public interface ITransactionAppService Task GetMerklePathByTransactionIdAsync(string transactionId); - Task GetTransactionFeeResultAsync(CalculateTransactionFeeInput input); + Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input); } \ No newline at end of file diff --git a/test/AElf.Client.Test/ClientTest.cs b/test/AElf.Client.Test/ClientTest.cs index 04d7f23..e0ed404 100644 --- a/test/AElf.Client.Test/ClientTest.cs +++ b/test/AElf.Client.Test/ClientTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Net; using System.Text; @@ -42,6 +43,7 @@ public class ClientTest private const string UserName = "test1"; private const string Password = "test"; + private const string Version = "1.2.3.0"; public ClientTest(ITestOutputHelper testOutputHelper) { @@ -166,6 +168,7 @@ public async Task GetNetworkInfo_Test() { var netWorkInfo = await Client.GetNetworkInfoAsync(); Assert.True(netWorkInfo != null); + netWorkInfo.Version.ShouldBe(Version); var info = JsonConvert.SerializeObject(netWorkInfo, Formatting.Indented); _testOutputHelper.WriteLine(info); } @@ -540,7 +543,7 @@ public void GetTransactionFee_Test() } [Fact] - public async void CalculateTransactionFeeResult_Test() + public async void CalculateTransactionFee_Test() { var address = GenesisAddress; var status = await Client.GetChainStatusAsync(); @@ -565,7 +568,7 @@ public async void CalculateTransactionFeeResult_Test() { RawTransaction = createRaw.RawTransaction }; - var transactionFeeOutput = await Client.GetTransactionFeeResultAsync(input); + var transactionFeeOutput = await Client.CalculateTransactionFeeAsync(input); transactionFeeOutput.Success.ShouldBe(true); transactionFeeOutput.TransactionFee["ELF"].ShouldBeGreaterThan(18000000); transactionFeeOutput.TransactionFee["ELF"].ShouldBeLessThanOrEqualTo(19000000); From 0a96c0c11149d8ecc6c561d86649c7653b06bcc0 Mon Sep 17 00:00:00 2001 From: wangyue Date: Wed, 8 Mar 2023 13:58:23 +0800 Subject: [PATCH 54/70] update file --- src/AElf.Client/AElfClient.Transaction.cs | 4 ++-- ...eeResultOutput.cs => CalculateTransactionFeeOutput.cs} | 2 +- src/AElf.Client/Services/ITransactionAppService.cs | 2 +- test/AElf.Client.Test/ClientTest.cs | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/AElf.Client/Dto/{TransactionFeeResultOutput.cs => CalculateTransactionFeeOutput.cs} (82%) diff --git a/src/AElf.Client/AElfClient.Transaction.cs b/src/AElf.Client/AElfClient.Transaction.cs index f8993af..0354fa5 100644 --- a/src/AElf.Client/AElfClient.Transaction.cs +++ b/src/AElf.Client/AElfClient.Transaction.cs @@ -163,13 +163,13 @@ public async Task ExecuteTransactionAsync(ExecuteTransactionDto input) return await _httpService.GetResponseAsync(url); } - public async Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input) + public async Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input) { var url = GetRequestUrl(_baseUrl, "/api/blockChain/calculateTransactionFee"); var parameters = new Dictionary { {"RawTransaction", input.RawTransaction} }; - return await _httpService.PostResponseAsync(url,parameters); + return await _httpService.PostResponseAsync(url,parameters); } } \ No newline at end of file diff --git a/src/AElf.Client/Dto/TransactionFeeResultOutput.cs b/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs similarity index 82% rename from src/AElf.Client/Dto/TransactionFeeResultOutput.cs rename to src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs index d415adc..cb79c6c 100644 --- a/src/AElf.Client/Dto/TransactionFeeResultOutput.cs +++ b/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs @@ -1,6 +1,6 @@ namespace AElf.Client.Dto; -public class TransactionFeeResultOutput +public class CalculateTransactionFeeOutput { public bool Success { get; set; } diff --git a/src/AElf.Client/Services/ITransactionAppService.cs b/src/AElf.Client/Services/ITransactionAppService.cs index 43cb338..31f7ca0 100644 --- a/src/AElf.Client/Services/ITransactionAppService.cs +++ b/src/AElf.Client/Services/ITransactionAppService.cs @@ -25,5 +25,5 @@ public interface ITransactionAppService Task GetMerklePathByTransactionIdAsync(string transactionId); - Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input); + Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input); } \ No newline at end of file diff --git a/test/AElf.Client.Test/ClientTest.cs b/test/AElf.Client.Test/ClientTest.cs index e0ed404..f4c63df 100644 --- a/test/AElf.Client.Test/ClientTest.cs +++ b/test/AElf.Client.Test/ClientTest.cs @@ -568,10 +568,10 @@ public async void CalculateTransactionFee_Test() { RawTransaction = createRaw.RawTransaction }; - var transactionFeeOutput = await Client.CalculateTransactionFeeAsync(input); - transactionFeeOutput.Success.ShouldBe(true); - transactionFeeOutput.TransactionFee["ELF"].ShouldBeGreaterThan(18000000); - transactionFeeOutput.TransactionFee["ELF"].ShouldBeLessThanOrEqualTo(19000000); + var calculateTransactionFeeOutput = await Client.CalculateTransactionFeeAsync(input); + calculateTransactionFeeOutput.Success.ShouldBe(true); + calculateTransactionFeeOutput.TransactionFee["ELF"].ShouldBeGreaterThan(18000000); + calculateTransactionFeeOutput.TransactionFee["ELF"].ShouldBeLessThanOrEqualTo(19000000); From 2a9a99af97d62aee7cbbbd6fdc6d51629a75549e Mon Sep 17 00:00:00 2001 From: gldeng Date: Tue, 27 Jun 2023 09:46:27 +0800 Subject: [PATCH 55/70] Support .netstandard2.1 --- .../AElf.Client.Protobuf.csproj | 6 +- src/AElf.Client/AElf.Client.csproj | 9 +- src/AElf.Client/AElfClient.Block.cs | 80 +-- src/AElf.Client/AElfClient.Chain.cs | 121 ++--- src/AElf.Client/AElfClient.Client.cs | 465 +++++++++--------- src/AElf.Client/AElfClient.Net.cs | 140 +++--- src/AElf.Client/AElfClient.Transaction.cs | 325 ++++++------ src/AElf.Client/AElfClient.cs | 70 +-- src/AElf.Client/AElfClientBuilder.cs | 123 ++--- src/AElf.Client/AElfClientConstants.cs | 25 +- src/AElf.Client/Dto/BlockBodyDto.cs | 15 +- src/AElf.Client/Dto/BlockDto.cs | 19 +- src/AElf.Client/Dto/BlockHeaderDto.cs | 47 +- .../Dto/CalculateTransactionFeeInput.cs | 11 +- .../Dto/CalculateTransactionFeeOutput.cs | 21 +- src/AElf.Client/Dto/ChainStatusDto.cs | 51 +- .../Dto/CreateRawTransactionInput.cs | 105 ++-- .../Dto/CreateRawTransactionOutput.cs | 11 +- .../Dto/ExecuteRawTransactionDto.cs | 27 +- src/AElf.Client/Dto/ExecuteTransactionDto.cs | 17 +- src/AElf.Client/Dto/LogEventDto.cs | 23 +- src/AElf.Client/Dto/MerklePathDto.cs | 23 +- src/AElf.Client/Dto/NetworkInfoOutput.cs | 37 +- src/AElf.Client/Dto/PeerDto.cs | 45 +- .../Dto/SendRawTransactionInput.cs | 37 +- .../Dto/SendRawTransactionOutput.cs | 15 +- src/AElf.Client/Dto/SendTransactionInput.cs | 17 +- src/AElf.Client/Dto/SendTransactionOutput.cs | 11 +- src/AElf.Client/Dto/SendTransactionsInput.cs | 17 +- src/AElf.Client/Dto/TaskQueueInfoDto.cs | 15 +- src/AElf.Client/Dto/TransactionDto.cs | 35 +- .../Dto/TransactionPoolStatusOutput.cs | 13 +- src/AElf.Client/Dto/TransactionResultDto.cs | 43 +- src/AElf.Client/EndpointType.cs | 19 +- .../Exception/AElfClientException.cs | 15 +- src/AElf.Client/Exception/Error.cs | 67 +-- .../Extensions/StringExtensions.cs | 21 +- .../TransactionResultDtoExtension.cs | 53 +- src/AElf.Client/GlobalUsings.cs | 1 - src/AElf.Client/Services/HttpService.cs | 369 +++++++------- src/AElf.Client/Services/IBlockAppService.cs | 20 +- src/AElf.Client/Services/IChainAppService.cs | 25 +- src/AElf.Client/Services/IClientService.cs | 23 +- src/AElf.Client/Services/INetAppService.cs | 25 +- .../Services/ITransactionAppService.cs | 55 ++- src/AElf.Client/TransactionBuilder.cs | 112 ++--- 46 files changed, 1433 insertions(+), 1391 deletions(-) delete mode 100644 src/AElf.Client/GlobalUsings.cs diff --git a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj index a582f80..825d508 100644 --- a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj +++ b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj @@ -1,17 +1,17 @@ - net6.0 - enable + netstandard2.1;net6.0 enable AElf.Client.Protobuf Protobuf using by AElf C# sdk. AElf true + 1.3.0 - + diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj index ffb9f1b..3df80b7 100644 --- a/src/AElf.Client/AElf.Client.csproj +++ b/src/AElf.Client/AElf.Client.csproj @@ -1,13 +1,14 @@ - net6.0 - enable + netstandard2.1;net6.0 enable AElf.Client This is a C# client library, used to communicate with the AElf API. AElf true + 1.3.0 + 9.0 @@ -15,8 +16,8 @@ - - + + diff --git a/src/AElf.Client/AElfClient.Block.cs b/src/AElf.Client/AElfClient.Block.cs index b6c7301..23a4141 100644 --- a/src/AElf.Client/AElfClient.Block.cs +++ b/src/AElf.Client/AElfClient.Block.cs @@ -1,44 +1,46 @@ +using System.Threading.Tasks; using AElf.Client.Dto; using AElf.Client.Services; -namespace AElf.Client; - -public partial class AElfClient : IBlockAppService +namespace AElf.Client { - /// - /// Get height of the current chain. - /// - /// Height - public async Task GetBlockHeightAsync() - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/blockHeight"); - return await _httpService.GetResponseAsync(url); - } - - /// - /// Get information of a block by given block hash. Optional whether to include transaction information. - /// - /// - /// - /// Block information - public async Task GetBlockByHashAsync(string blockHash, bool includeTransactions = false) - { - AssertValidHash(blockHash); - var url = GetRequestUrl(_baseUrl, - $"api/blockChain/block?blockHash={blockHash}&includeTransactions={includeTransactions}"); - return await _httpService.GetResponseAsync(url); - } - - /// - /// Get information of a block by specified height. Optional whether to include transaction information. - /// - /// - /// - /// Block information - public async Task GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false) + + public partial class AElfClient : IBlockAppService { - var url = GetRequestUrl(_baseUrl, - $"api/blockChain/blockByHeight?blockHeight={blockHeight}&includeTransactions={includeTransactions}"); - return await _httpService.GetResponseAsync(url); - } -} \ No newline at end of file + /// + /// Get height of the current chain. + /// + /// Height + public async Task GetBlockHeightAsync() + { + var url = GetRequestUrl(_baseUrl, "api/blockChain/blockHeight"); + return await _httpService.GetResponseAsync(url); + } + + /// + /// Get information of a block by given block hash. Optional whether to include transaction information. + /// + /// + /// + /// Block information + public async Task GetBlockByHashAsync(string blockHash, bool includeTransactions = false) + { + AssertValidHash(blockHash); + var url = GetRequestUrl(_baseUrl, + $"api/blockChain/block?blockHash={blockHash}&includeTransactions={includeTransactions}"); + return await _httpService.GetResponseAsync(url); + } + + /// + /// Get information of a block by specified height. Optional whether to include transaction information. + /// + /// + /// + /// Block information + public async Task GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false) + { + var url = GetRequestUrl(_baseUrl, + $"api/blockChain/blockByHeight?blockHeight={blockHeight}&includeTransactions={includeTransactions}"); + return await _httpService.GetResponseAsync(url); + } + }} diff --git a/src/AElf.Client/AElfClient.Chain.cs b/src/AElf.Client/AElfClient.Chain.cs index e42eb0f..08289e7 100644 --- a/src/AElf.Client/AElfClient.Chain.cs +++ b/src/AElf.Client/AElfClient.Chain.cs @@ -1,69 +1,72 @@ +using System.Collections.Generic; +using System.Threading.Tasks; using AElf.Client.Dto; -namespace AElf.Client; - -public partial class AElfClient : IChainAppService +namespace AElf.Client { - /// - /// Get the current status of the block chain. - /// - /// Description of current status - public async Task GetChainStatusAsync() + + public partial class AElfClient : IChainAppService { - var url = GetRequestUrl(_baseUrl, "api/blockChain/chainStatus"); - var chainStatus = await _httpService.GetResponseAsync(url); - if (chainStatus == null) + /// + /// Get the current status of the block chain. + /// + /// Description of current status + public async Task GetChainStatusAsync() { - throw new AElfClientException("Failed to get chain status"); + var url = GetRequestUrl(_baseUrl, "api/blockChain/chainStatus"); + var chainStatus = await _httpService.GetResponseAsync(url); + if (chainStatus == null) + { + throw new AElfClientException("Failed to get chain status"); + } + + return chainStatus; } - - return chainStatus; - } - - /// - /// Get the definitions of proto-buff related to a contract. - /// - /// - /// Definitions of proto-buff - public async Task GetContractFileDescriptorSetAsync(string? address) - { - AssertValidAddress(address); - var url = GetRequestUrl(_baseUrl, $"api/blockChain/contractFileDescriptorSet?address={address}"); - var set = await _httpService.GetResponseAsync(url); - if (set == null) + + /// + /// Get the definitions of proto-buff related to a contract. + /// + /// + /// Definitions of proto-buff + public async Task GetContractFileDescriptorSetAsync(string? address) { - throw new AElfClientException("Failed to get chain status"); + AssertValidAddress(address); + var url = GetRequestUrl(_baseUrl, $"api/blockChain/contractFileDescriptorSet?address={address}"); + var set = await _httpService.GetResponseAsync(url); + if (set == null) + { + throw new AElfClientException("Failed to get chain status"); + } + + return set; } - - return set; - } - - /// - /// Gets the status information of the task queue. - /// - /// Information of the task queue - public async Task> GetTaskQueueStatusAsync() - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/taskQueueStatus"); - - var taskQueueInfoList = await _httpService.GetResponseAsync>(url); - if (taskQueueInfoList == null) + + /// + /// Gets the status information of the task queue. + /// + /// Information of the task queue + public async Task> GetTaskQueueStatusAsync() { - throw new AElfClientException("Failed to get chain status"); + var url = GetRequestUrl(_baseUrl, "api/blockChain/taskQueueStatus"); + + var taskQueueInfoList = await _httpService.GetResponseAsync>(url); + if (taskQueueInfoList == null) + { + throw new AElfClientException("Failed to get chain status"); + } + + return taskQueueInfoList; } - - return taskQueueInfoList; - } - - /// - /// Get id of the chain. - /// - /// ChainId - public async Task GetChainIdAsync() - { - var chainStatus = await GetChainStatusAsync(); - var base58ChainId = chainStatus.ChainId; - var chainId = ChainHelper.ConvertBase58ToChainId(base58ChainId); - return chainId; - } -} \ No newline at end of file + + /// + /// Get id of the chain. + /// + /// ChainId + public async Task GetChainIdAsync() + { + var chainStatus = await GetChainStatusAsync(); + var base58ChainId = chainStatus.ChainId; + var chainId = ChainHelper.ConvertBase58ToChainId(base58ChainId); + return chainId; + } + }} diff --git a/src/AElf.Client/AElfClient.Client.cs b/src/AElf.Client/AElfClient.Client.cs index c187395..4fdf3e8 100644 --- a/src/AElf.Client/AElfClient.Client.cs +++ b/src/AElf.Client/AElfClient.Client.cs @@ -1,268 +1,273 @@ +using System; +using System.Linq; +using System.Threading.Tasks; using AElf.Client.Dto; using AElf.Client.Extensions; using AElf.Client.Model; using AElf.Client.Services; using AElf.Cryptography; using AElf.Cryptography.ECDSA; +using AElf.Types; using Google.Protobuf; using Google.Protobuf.WellKnownTypes; -namespace AElf.Client; - -public partial class AElfClient : IClientService +namespace AElf.Client { - /// - /// Verify whether this sdk successfully connects the chain. - /// - /// IsConnected or not - public async Task IsConnectedAsync() - { - try + + public partial class AElfClient : IClientService + { + /// + /// Verify whether this sdk successfully connects the chain. + /// + /// IsConnected or not + public async Task IsConnectedAsync() { - var chainStatus = await GetChainStatusAsync(); - return chainStatus != null; + try + { + var chainStatus = await GetChainStatusAsync(); + return chainStatus != null; + } + catch (Exception) + { + return false; + } } - catch (Exception) + + /// + /// Get the address of genesis contract. + /// + /// Address + public async Task GetGenesisContractAddressAsync() { - return false; + var statusDto = await GetChainStatusAsync(); + var genesisAddress = statusDto?.GenesisContractAddress; + return genesisAddress; } - } - - /// - /// Get the address of genesis contract. - /// - /// Address - public async Task GetGenesisContractAddressAsync() - { - var statusDto = await GetChainStatusAsync(); - var genesisAddress = statusDto?.GenesisContractAddress; - return genesisAddress; - } - - /// - /// Get address of a contract by given contractNameHash. - /// - /// - /// Address - public async Task
GetContractAddressByNameAsync(Hash contractNameHash) - { - var from = GetAddressFromPrivateKey(AElfClientConstants.DefaultPrivateKey); - var to = await GetGenesisContractAddressAsync(); - var transaction = await GenerateTransactionAsync(from, to, "GetContractAddressByName", contractNameHash); - var txWithSig = SignTransaction(AElfClientConstants.DefaultPrivateKey, transaction); - - var response = await ExecuteTransactionAsync(new ExecuteTransactionDto + + /// + /// Get address of a contract by given contractNameHash. + /// + /// + /// Address + public async Task
GetContractAddressByNameAsync(Hash contractNameHash) { - RawTransaction = txWithSig.ToByteArray().ToHex() - }); - var byteArray = ByteArrayHelper.HexStringToByteArray(response); - var address = Address.Parser.ParseFrom(byteArray); - - return address; - } - - /// - /// Build a transaction from the input parameters. - /// - /// - /// - /// - /// - /// Transaction unsigned - public async Task GenerateTransactionAsync(string? from, string? to, - string methodName, IMessage input) - { - try + var from = GetAddressFromPrivateKey(AElfClientConstants.DefaultPrivateKey); + var to = await GetGenesisContractAddressAsync(); + var transaction = await GenerateTransactionAsync(from, to, "GetContractAddressByName", contractNameHash); + var txWithSig = SignTransaction(AElfClientConstants.DefaultPrivateKey, transaction); + + var response = await ExecuteTransactionAsync(new ExecuteTransactionDto + { + RawTransaction = txWithSig.ToByteArray().ToHex() + }); + var byteArray = ByteArrayHelper.HexStringToByteArray(response); + var address = Address.Parser.ParseFrom(byteArray); + + return address; + } + + /// + /// Build a transaction from the input parameters. + /// + /// + /// + /// + /// + /// Transaction unsigned + public async Task GenerateTransactionAsync(string? from, string? to, + string methodName, IMessage input) { - AssertValidAddress(to); - var chainStatus = await GetChainStatusAsync(); - var transaction = new Transaction + try { - From = from.ToAddress(), - To = Address.FromBase58(to), - MethodName = methodName, - Params = input.ToByteString(), - RefBlockNumber = chainStatus.BestChainHeight, - RefBlockPrefix = ByteString.CopyFrom(Hash.LoadFromHex(chainStatus.BestChainHash).Value - .Take(4).ToArray()) - }; - + AssertValidAddress(to); + var chainStatus = await GetChainStatusAsync(); + var transaction = new Transaction + { + From = from.ToAddress(), + To = Address.FromBase58(to), + MethodName = methodName, + Params = input.ToByteString(), + RefBlockNumber = chainStatus.BestChainHeight, + RefBlockPrefix = ByteString.CopyFrom(Hash.LoadFromHex(chainStatus.BestChainHash).Value + .Take(4).ToArray()) + }; + + return transaction; + } + catch (Exception ex) + { + throw new AElfClientException($"Failed to generate transaction: {ex.Message}"); + } + } + + /// + /// Convert the Address to the displayed string:symbol_base58-string_base58-string-chain-id + /// + /// + /// + public async Task GetFormattedAddressAsync(Address address) + { + var tokenContractAddress = await GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); + var fromAddress = GetAddressFromPrivateKey(AElfClientConstants.DefaultPrivateKey); + var toAddress = tokenContractAddress.ToBase58(); + var methodName = "GetPrimaryTokenSymbol"; + var param = new Empty(); + + var transaction = await GenerateTransactionAsync(fromAddress, toAddress, methodName, param); + var txWithSign = SignTransaction(AElfClientConstants.DefaultPrivateKey, transaction); + + var result = await ExecuteTransactionAsync(new ExecuteTransactionDto + { + RawTransaction = txWithSign.ToByteArray().ToHex() + }); + + var symbol = StringValue.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(result)); + var chainIdString = (await GetChainStatusAsync())?.ChainId; + + return $"{symbol.Value}_{address.ToBase58()}_{chainIdString}"; + } + + /// + /// Sign a transaction using private key. + /// + /// + /// + /// Transaction signed + public Transaction SignTransaction(string? privateKeyHex, Transaction transaction) + { + var transactionData = transaction.GetHash().ToByteArray(); + + privateKeyHex ??= AElfClientConstants.DefaultPrivateKey; + + // Sign the hash + var privateKey = ByteArrayHelper.HexStringToByteArray(privateKeyHex); + var signature = CryptoHelper.SignWithPrivateKey(privateKey, transactionData); + transaction.Signature = ByteString.CopyFrom(signature); + return transaction; } - catch (Exception ex) + + /// + /// Sign a transaction using private key. + /// + /// + /// + /// Transaction signed + public Transaction SignTransaction(byte[]? privateKey, Transaction transaction) { - throw new AElfClientException($"Failed to generate transaction: {ex.Message}"); + var transactionData = transaction.GetHash().ToByteArray(); + + privateKey ??= ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey); + + // Sign the hash + var signature = CryptoHelper.SignWithPrivateKey(privateKey, transactionData); + transaction.Signature = ByteString.CopyFrom(signature); + + return transaction; } - } - - /// - /// Convert the Address to the displayed string:symbol_base58-string_base58-string-chain-id - /// - /// - /// - public async Task GetFormattedAddressAsync(Address address) - { - var tokenContractAddress = await GetContractAddressByNameAsync(HashHelper.ComputeFrom("AElf.ContractNames.Token")); - var fromAddress = GetAddressFromPrivateKey(AElfClientConstants.DefaultPrivateKey); - var toAddress = tokenContractAddress.ToBase58(); - var methodName = "GetPrimaryTokenSymbol"; - var param = new Empty(); - - var transaction = await GenerateTransactionAsync(fromAddress, toAddress, methodName, param); - var txWithSign = SignTransaction(AElfClientConstants.DefaultPrivateKey, transaction); - - var result = await ExecuteTransactionAsync(new ExecuteTransactionDto + + /// + /// Get the account address through the public key. + /// + /// + /// Account + public string GetAddressFromPubKey(string pubKey) { - RawTransaction = txWithSign.ToByteArray().ToHex() - }); - - var symbol = StringValue.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(result)); - var chainIdString = (await GetChainStatusAsync())?.ChainId; - - return $"{symbol.Value}_{address.ToBase58()}_{chainIdString}"; - } - - /// - /// Sign a transaction using private key. - /// - /// - /// - /// Transaction signed - public Transaction SignTransaction(string? privateKeyHex, Transaction transaction) - { - var transactionData = transaction.GetHash().ToByteArray(); - - privateKeyHex ??= AElfClientConstants.DefaultPrivateKey; - - // Sign the hash - var privateKey = ByteArrayHelper.HexStringToByteArray(privateKeyHex); - var signature = CryptoHelper.SignWithPrivateKey(privateKey, transactionData); - transaction.Signature = ByteString.CopyFrom(signature); - - return transaction; - } - - /// - /// Sign a transaction using private key. - /// - /// - /// - /// Transaction signed - public Transaction SignTransaction(byte[]? privateKey, Transaction transaction) - { - var transactionData = transaction.GetHash().ToByteArray(); - - privateKey ??= ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey); - - // Sign the hash - var signature = CryptoHelper.SignWithPrivateKey(privateKey, transactionData); - transaction.Signature = ByteString.CopyFrom(signature); - - return transaction; - } - - /// - /// Get the account address through the public key. - /// - /// - /// Account - public string GetAddressFromPubKey(string pubKey) - { - var publicKey = ByteArrayHelper.HexStringToByteArray(pubKey); - var address = Address.FromPublicKey(publicKey); - return address.ToBase58(); - } - - /// - /// Get the account address through the private key. - /// - /// - /// - public string? GetAddressFromPrivateKey(string? privateKeyHex) - { - var address = Address.FromPublicKey(GetAElfKeyPair(privateKeyHex).PublicKey); - return address.ToBase58(); - } - - public Address GetBase58String(string base58String) - { - return Address.FromBase58(base58String); - } - - public KeyPairInfo GenerateKeyPairInfo() - { - var keyPair = CryptoHelper.GenerateKeyPair(); - var privateKey = keyPair.PrivateKey.ToHex(); - var publicKey = keyPair.PublicKey.ToHex(); - var address = GetAddressFromPrivateKey(privateKey); - - return new KeyPairInfo + var publicKey = ByteArrayHelper.HexStringToByteArray(pubKey); + var address = Address.FromPublicKey(publicKey); + return address.ToBase58(); + } + + /// + /// Get the account address through the private key. + /// + /// + /// + public string? GetAddressFromPrivateKey(string? privateKeyHex) { - PrivateKey = privateKey, - PublicKey = publicKey, - Address = address - }; - } - - #region private methods - - private ECKeyPair GetAElfKeyPair(string? privateKeyHex) - { - var privateKey = ByteArrayHelper.HexStringToByteArray(privateKeyHex); - var keyPair = CryptoHelper.FromPrivateKey(privateKey); - - return keyPair; - } - - private string GetRequestUrl(string baseUrl, string relativeUrl) - { - return new Uri(new Uri(baseUrl + (baseUrl.EndsWith("/") ? "" : "/")), relativeUrl).ToString(); - } - - private void AssertValidAddress(params string?[] addresses) - { - try + var address = Address.FromPublicKey(GetAElfKeyPair(privateKeyHex).PublicKey); + return address.ToBase58(); + } + + public Address GetBase58String(string base58String) { - foreach (var address in addresses) + return Address.FromBase58(base58String); + } + + public KeyPairInfo GenerateKeyPairInfo() + { + var keyPair = CryptoHelper.GenerateKeyPair(); + var privateKey = keyPair.PrivateKey.ToHex(); + var publicKey = keyPair.PublicKey.ToHex(); + var address = GetAddressFromPrivateKey(privateKey); + + return new KeyPairInfo { - Address.FromBase58(address); - } + PrivateKey = privateKey, + PublicKey = publicKey, + Address = address + }; } - catch (Exception) + + #region private methods + + private ECKeyPair GetAElfKeyPair(string? privateKeyHex) { - throw new AElfClientException(Error.Message[Error.InvalidAddress]); + var privateKey = ByteArrayHelper.HexStringToByteArray(privateKeyHex); + var keyPair = CryptoHelper.FromPrivateKey(privateKey); + + return keyPair; } - } - - private void AssertValidHash(params string[] hashes) - { - try + + private string GetRequestUrl(string baseUrl, string relativeUrl) { - foreach (var hash in hashes) - { - Hash.LoadFromHex(hash); - } + return new Uri(new Uri(baseUrl + (baseUrl.EndsWith("/") ? "" : "/")), relativeUrl).ToString(); } - catch (Exception) + + private void AssertValidAddress(params string?[] addresses) { - throw new AElfClientException(Error.Message[Error.InvalidBlockHash]); + try + { + foreach (var address in addresses) + { + Address.FromBase58(address); + } + } + catch (Exception) + { + throw new AElfClientException(Error.Message[Error.InvalidAddress]); + } } - } - - private void AssertValidTransactionId(params string[] transactionIds) - { - try + + private void AssertValidHash(params string[] hashes) { - foreach (var transactionId in transactionIds) + try { - Hash.LoadFromHex(transactionId); + foreach (var hash in hashes) + { + Hash.LoadFromHex(hash); + } + } + catch (Exception) + { + throw new AElfClientException(Error.Message[Error.InvalidBlockHash]); } } - catch (Exception) + + private void AssertValidTransactionId(params string[] transactionIds) { - throw new AElfClientException(Error.Message[Error.InvalidTransactionId]); + try + { + foreach (var transactionId in transactionIds) + { + Hash.LoadFromHex(transactionId); + } + } + catch (Exception) + { + throw new AElfClientException(Error.Message[Error.InvalidTransactionId]); + } } - } - - #endregion -} \ No newline at end of file + + #endregion + }} diff --git a/src/AElf.Client/AElfClient.Net.cs b/src/AElf.Client/AElfClient.Net.cs index 89b2f5b..05b1dea 100644 --- a/src/AElf.Client/AElfClient.Net.cs +++ b/src/AElf.Client/AElfClient.Net.cs @@ -1,80 +1,84 @@ +using System; +using System.Collections.Generic; using System.Net.Http.Headers; using System.Text; +using System.Threading.Tasks; using AElf.Client.Dto; using AElf.Client.Helper; using AElf.Client.Services; -namespace AElf.Client; - -public partial class AElfClient : INetAppService +namespace AElf.Client { - /// - /// Attempt to add a node to the connected network nodes.Input parameter contains the ipAddress of the node. - /// - /// - /// - /// - /// Add successfully or not - public async Task AddPeerAsync(string ipAddress, string userName, string password) - { - if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) + + public partial class AElfClient : INetAppService + { + /// + /// Attempt to add a node to the connected network nodes.Input parameter contains the ipAddress of the node. + /// + /// + /// + /// + /// Add successfully or not + public async Task AddPeerAsync(string ipAddress, string userName, string password) { - return false; + if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) + { + return false; + } + + var url = GetRequestUrl(_baseUrl, "api/net/peer"); + var parameters = new Dictionary + { + {"address", endpoint?.ToString() ?? AElfClientConstants.LocalEndpoint} + }; + + return await _httpService.PostResponseAsync(url, parameters, + authenticationHeaderValue: GetAuthenticationHeaderValue()); } - - var url = GetRequestUrl(_baseUrl, "api/net/peer"); - var parameters = new Dictionary + + /// + /// Attempt to remove a node from the connected network nodes by given the ipAddress. + /// + /// + /// + /// + /// Delete successfully or not + public async Task RemovePeerAsync(string ipAddress, string userName, string password) { - {"address", endpoint?.ToString() ?? AElfClientConstants.LocalEndpoint} - }; - - return await _httpService.PostResponseAsync(url, parameters, - authenticationHeaderValue: GetAuthenticationHeaderValue()); - } - - /// - /// Attempt to remove a node from the connected network nodes by given the ipAddress. - /// - /// - /// - /// - /// Delete successfully or not - public async Task RemovePeerAsync(string ipAddress, string userName, string password) - { - if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) + if (!EndpointHelper.TryParse(ipAddress, out var endpoint)) + { + return false; + } + + var url = GetRequestUrl(_baseUrl, $"api/net/peer?address={endpoint}"); + return await _httpService.DeleteResponseAsObjectAsync(url, + authenticationHeaderValue: GetAuthenticationHeaderValue()); + } + + /// + /// Gets information about the peer nodes of the current node.Optional whether to include metrics. + /// + /// + /// Information about the peer nodes + public async Task?> GetPeersAsync(bool withMetrics) { - return false; + var url = GetRequestUrl(_baseUrl, $"api/net/peers?withMetrics={withMetrics}"); + return await _httpService.GetResponseAsync>(url); } - - var url = GetRequestUrl(_baseUrl, $"api/net/peer?address={endpoint}"); - return await _httpService.DeleteResponseAsObjectAsync(url, - authenticationHeaderValue: GetAuthenticationHeaderValue()); - } - - /// - /// Gets information about the peer nodes of the current node.Optional whether to include metrics. - /// - /// - /// Information about the peer nodes - public async Task?> GetPeersAsync(bool withMetrics) - { - var url = GetRequestUrl(_baseUrl, $"api/net/peers?withMetrics={withMetrics}"); - return await _httpService.GetResponseAsync>(url); - } - - /// - /// Get the node's network information. - /// - /// Network information - public async Task GetNetworkInfoAsync() - { - var url = GetRequestUrl(_baseUrl, "api/net/networkInfo"); - return await _httpService.GetResponseAsync(url); - } - - private AuthenticationHeaderValue GetAuthenticationHeaderValue() - { - var byteArray = Encoding.ASCII.GetBytes($"{_userName}:{_password}"); - return new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); - } -} \ No newline at end of file + + /// + /// Get the node's network information. + /// + /// Network information + public async Task GetNetworkInfoAsync() + { + var url = GetRequestUrl(_baseUrl, "api/net/networkInfo"); + return await _httpService.GetResponseAsync(url); + } + + private AuthenticationHeaderValue GetAuthenticationHeaderValue() + { + var byteArray = Encoding.ASCII.GetBytes($"{_userName}:{_password}"); + return new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); + } + }} diff --git a/src/AElf.Client/AElfClient.Transaction.cs b/src/AElf.Client/AElfClient.Transaction.cs index 0354fa5..e41d17b 100644 --- a/src/AElf.Client/AElfClient.Transaction.cs +++ b/src/AElf.Client/AElfClient.Transaction.cs @@ -1,175 +1,178 @@ +using System.Collections.Generic; +using System.Threading.Tasks; using AElf.Client.Dto; using AElf.Client.Services; -namespace AElf.Client; - -public partial class AElfClient : ITransactionAppService +namespace AElf.Client { - /// - /// Get information about the current transaction pool. - /// - /// TransactionPoolStatusOutput - public async Task GetTransactionPoolStatusAsync() - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/transactionPoolStatus"); - return await _httpService.GetResponseAsync(url); - } - + + public partial class AElfClient : ITransactionAppService + { /// - /// Call a read-only method of a contract. - /// - /// - /// - public async Task ExecuteTransactionAsync(ExecuteTransactionDto input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/executeTransaction"); - var parameters = new Dictionary + /// Get information about the current transaction pool. + ///
+ /// TransactionPoolStatusOutput + public async Task GetTransactionPoolStatusAsync() { - {"RawTransaction", input.RawTransaction} - }; - - var result = await _httpService.PostResponseAsync(url, parameters); - - if (result == null) + var url = GetRequestUrl(_baseUrl, "api/blockChain/transactionPoolStatus"); + return await _httpService.GetResponseAsync(url); + } + + /// + /// Call a read-only method of a contract. + /// + /// + /// + public async Task ExecuteTransactionAsync(ExecuteTransactionDto input) { - throw new AElfClientException("Failed to execute tx."); + var url = GetRequestUrl(_baseUrl, "api/blockChain/executeTransaction"); + var parameters = new Dictionary + { + {"RawTransaction", input.RawTransaction} + }; + + var result = await _httpService.PostResponseAsync(url, parameters); + + if (result == null) + { + throw new AElfClientException("Failed to execute tx."); + } + + return result; } - - return result; - } - - /// - /// Call a method of a contract by given serialized strings. - /// - /// - /// Serialized result - public async Task ExecuteRawTransactionAsync(ExecuteRawTransactionDto input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/executeRawTransaction"); - var parameters = new Dictionary + + /// + /// Call a method of a contract by given serialized strings. + /// + /// + /// Serialized result + public async Task ExecuteRawTransactionAsync(ExecuteRawTransactionDto input) { - {"RawTransaction", input.RawTransaction}, - {"Signature", input.Signature} - }; - - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Creates an unsigned serialized transaction. - /// - /// - /// CreateRawTransactionOutput - public async Task CreateRawTransactionAsync(CreateRawTransactionInput input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/rawTransaction"); - var parameters = new Dictionary + var url = GetRequestUrl(_baseUrl, "api/blockChain/executeRawTransaction"); + var parameters = new Dictionary + { + {"RawTransaction", input.RawTransaction}, + {"Signature", input.Signature} + }; + + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Creates an unsigned serialized transaction. + /// + /// + /// CreateRawTransactionOutput + public async Task CreateRawTransactionAsync(CreateRawTransactionInput input) { - {"From", input.From}, - {"To", input.To}, - {"RefBlockNumber", input.RefBlockNumber.ToString()}, - {"RefBlockHash", input.RefBlockHash}, - {"MethodName", input.MethodName}, - {"Params", input.Params} - }; - - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Broadcast a serialized transaction. - /// - /// - /// SendRawTransactionOutput - public async Task SendRawTransactionAsync(SendRawTransactionInput input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/sendRawTransaction"); - var parameters = new Dictionary + var url = GetRequestUrl(_baseUrl, "api/blockChain/rawTransaction"); + var parameters = new Dictionary + { + {"From", input.From}, + {"To", input.To}, + {"RefBlockNumber", input.RefBlockNumber.ToString()}, + {"RefBlockHash", input.RefBlockHash}, + {"MethodName", input.MethodName}, + {"Params", input.Params} + }; + + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Broadcast a serialized transaction. + /// + /// + /// SendRawTransactionOutput + public async Task SendRawTransactionAsync(SendRawTransactionInput input) { - {"Transaction", input.Transaction}, - {"Signature", input.Signature}, - {"ReturnTransaction", input.ReturnTransaction ? "true" : "false"} - }; - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Broadcast a transaction. - /// - /// - /// TransactionId - public async Task SendTransactionAsync(SendTransactionInput input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/sendTransaction"); - var parameters = new Dictionary + var url = GetRequestUrl(_baseUrl, "api/blockChain/sendRawTransaction"); + var parameters = new Dictionary + { + {"Transaction", input.Transaction}, + {"Signature", input.Signature}, + {"ReturnTransaction", input.ReturnTransaction ? "true" : "false"} + }; + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Broadcast a transaction. + /// + /// + /// TransactionId + public async Task SendTransactionAsync(SendTransactionInput input) { - {"RawTransaction", input.RawTransaction} - }; - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Broadcast volume transactions. - /// - /// - /// TransactionIds - public async Task SendTransactionsAsync(SendTransactionsInput input) - { - var url = GetRequestUrl(_baseUrl, "api/blockChain/sendTransactions"); - var parameters = new Dictionary + var url = GetRequestUrl(_baseUrl, "api/blockChain/sendTransaction"); + var parameters = new Dictionary + { + {"RawTransaction", input.RawTransaction} + }; + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Broadcast volume transactions. + /// + /// + /// TransactionIds + public async Task SendTransactionsAsync(SendTransactionsInput input) { - {"RawTransactions", input.RawTransactions} - }; - return await _httpService.PostResponseAsync(url, parameters); - } - - /// - /// Gets the result of transaction execution by the given transactionId. - /// - /// - /// TransactionResultDto - public async Task GetTransactionResultAsync(string transactionId) - { - AssertValidTransactionId(transactionId); - var url = GetRequestUrl(_baseUrl, $"api/blockChain/transactionResult?transactionId={transactionId}"); - return await _httpService.GetResponseAsync(url); - } - - /// - /// Get results of multiple transactions by specified blockHash and the offset. - /// - /// - /// - /// - /// TransactionResultDtos - public async Task?> GetTransactionResultsAsync(string blockHash, int offset = 0, - int limit = 10) - { - AssertValidHash(blockHash); - var url = GetRequestUrl(_baseUrl, - $"api/blockChain/transactionResults?blockHash={blockHash}&offset={offset}&limit={limit}"); - return await _httpService.GetResponseAsync>(url); - } - - /// - /// Get merkle path of a transaction. - /// - /// - /// MerklePathDto - public async Task GetMerklePathByTransactionIdAsync(string transactionId) - { - AssertValidTransactionId(transactionId); - var url = GetRequestUrl(_baseUrl, $"api/blockChain/merklePathByTransactionId?transactionId={transactionId}"); - return await _httpService.GetResponseAsync(url); - } - - public async Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input) - { - var url = GetRequestUrl(_baseUrl, "/api/blockChain/calculateTransactionFee"); - var parameters = new Dictionary + var url = GetRequestUrl(_baseUrl, "api/blockChain/sendTransactions"); + var parameters = new Dictionary + { + {"RawTransactions", input.RawTransactions} + }; + return await _httpService.PostResponseAsync(url, parameters); + } + + /// + /// Gets the result of transaction execution by the given transactionId. + /// + /// + /// TransactionResultDto + public async Task GetTransactionResultAsync(string transactionId) { - {"RawTransaction", input.RawTransaction} - }; - return await _httpService.PostResponseAsync(url,parameters); - } -} \ No newline at end of file + AssertValidTransactionId(transactionId); + var url = GetRequestUrl(_baseUrl, $"api/blockChain/transactionResult?transactionId={transactionId}"); + return await _httpService.GetResponseAsync(url); + } + + /// + /// Get results of multiple transactions by specified blockHash and the offset. + /// + /// + /// + /// + /// TransactionResultDtos + public async Task?> GetTransactionResultsAsync(string blockHash, int offset = 0, + int limit = 10) + { + AssertValidHash(blockHash); + var url = GetRequestUrl(_baseUrl, + $"api/blockChain/transactionResults?blockHash={blockHash}&offset={offset}&limit={limit}"); + return await _httpService.GetResponseAsync>(url); + } + + /// + /// Get merkle path of a transaction. + /// + /// + /// MerklePathDto + public async Task GetMerklePathByTransactionIdAsync(string transactionId) + { + AssertValidTransactionId(transactionId); + var url = GetRequestUrl(_baseUrl, $"api/blockChain/merklePathByTransactionId?transactionId={transactionId}"); + return await _httpService.GetResponseAsync(url); + } + + public async Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input) + { + var url = GetRequestUrl(_baseUrl, "/api/blockChain/calculateTransactionFee"); + var parameters = new Dictionary + { + {"RawTransaction", input.RawTransaction} + }; + return await _httpService.PostResponseAsync(url,parameters); + } + }} diff --git a/src/AElf.Client/AElfClient.cs b/src/AElf.Client/AElfClient.cs index a45bb29..fdfc16a 100644 --- a/src/AElf.Client/AElfClient.cs +++ b/src/AElf.Client/AElfClient.cs @@ -1,38 +1,40 @@ -using System.Text.Json; +using System; +using System.Text.Json; using AElf.Client.Service; -namespace AElf.Client; - -public partial class AElfClient : IDisposable +namespace AElf.Client { - private readonly IHttpService _httpService; - private readonly string _baseUrl; - private readonly string _userName; - private readonly string _password; - - public AElfClient(string baseUrl, int timeOut = 60, string userName = null, string password = null) - { - _httpService = new HttpService(timeOut); - _baseUrl = baseUrl; - _userName = userName; - _password = password; - } - - private bool _disposed; - - /// - public void Dispose() - { - if (_disposed) return; - Dispose(true); - _disposed = true; - } - - /// - /// Disposes the resources associated with the object. - /// - /// true if called by a call to the Dispose method; otherwise false. - protected virtual void Dispose(bool disposing) + + public partial class AElfClient : IDisposable { - } -} \ No newline at end of file + private readonly IHttpService _httpService; + private readonly string _baseUrl; + private readonly string _userName; + private readonly string _password; + + public AElfClient(string baseUrl, int timeOut = 60, string userName = null, string password = null) + { + _httpService = new HttpService(timeOut); + _baseUrl = baseUrl; + _userName = userName; + _password = password; + } + + private bool _disposed; + + /// + public void Dispose() + { + if (_disposed) return; + Dispose(true); + _disposed = true; + } + + /// + /// Disposes the resources associated with the object. + /// + /// true if called by a call to the Dispose method; otherwise false. + protected virtual void Dispose(bool disposing) + { + } + }} diff --git a/src/AElf.Client/AElfClientBuilder.cs b/src/AElf.Client/AElfClientBuilder.cs index c2a04fe..409522a 100644 --- a/src/AElf.Client/AElfClientBuilder.cs +++ b/src/AElf.Client/AElfClientBuilder.cs @@ -1,65 +1,66 @@ -namespace AElf.Client; - -public sealed class AElfClientBuilder +namespace AElf.Client { - private string NodeEndpoint { get; set; } - private int Timeout { get; set; } - - private string UserName { get; set; } - private string Password { get; set; } - - public AElfClientBuilder() + + public sealed class AElfClientBuilder { - NodeEndpoint = AElfClientConstants.LocalEndpoint; - Timeout = 60; - } - - public AElfClientBuilder UseEndpoint(string endpoint) - { - NodeEndpoint = endpoint; - return this; - } - - public AElfClientBuilder UsePublicEndpoint(EndpointType endpointType) - { - switch (endpointType) + private string NodeEndpoint { get; set; } + private int Timeout { get; set; } + + private string UserName { get; set; } + private string Password { get; set; } + + public AElfClientBuilder() { - case EndpointType.MainNetMainChain: - NodeEndpoint = AElfClientConstants.MainNetMainChain; - break; - case EndpointType.MainNetSidechain: - NodeEndpoint = AElfClientConstants.MainNetSidechain; - break; - case EndpointType.TestNetMainChain: - NodeEndpoint = AElfClientConstants.TestNetMainChain; - break; - case EndpointType.TestNetSidechain: - NodeEndpoint = AElfClientConstants.TestNetSidechain; - break; - case EndpointType.Local: - default: - NodeEndpoint = AElfClientConstants.LocalEndpoint; - break; + NodeEndpoint = AElfClientConstants.LocalEndpoint; + Timeout = 60; } - - return this; - } - - public AElfClientBuilder SetHttpTimeout(int timeout) - { - Timeout = timeout; - return this; - } - - public AElfClientBuilder ManagePeerInfo(string userName, string password) - { - UserName = userName; - Password = password; - return this; - } - - public AElfClient Build() - { - return new AElfClient(NodeEndpoint, Timeout, UserName, Password); - } -} \ No newline at end of file + + public AElfClientBuilder UseEndpoint(string endpoint) + { + NodeEndpoint = endpoint; + return this; + } + + public AElfClientBuilder UsePublicEndpoint(EndpointType endpointType) + { + switch (endpointType) + { + case EndpointType.MainNetMainChain: + NodeEndpoint = AElfClientConstants.MainNetMainChain; + break; + case EndpointType.MainNetSidechain: + NodeEndpoint = AElfClientConstants.MainNetSidechain; + break; + case EndpointType.TestNetMainChain: + NodeEndpoint = AElfClientConstants.TestNetMainChain; + break; + case EndpointType.TestNetSidechain: + NodeEndpoint = AElfClientConstants.TestNetSidechain; + break; + case EndpointType.Local: + default: + NodeEndpoint = AElfClientConstants.LocalEndpoint; + break; + } + + return this; + } + + public AElfClientBuilder SetHttpTimeout(int timeout) + { + Timeout = timeout; + return this; + } + + public AElfClientBuilder ManagePeerInfo(string userName, string password) + { + UserName = userName; + Password = password; + return this; + } + + public AElfClient Build() + { + return new AElfClient(NodeEndpoint, Timeout, UserName, Password); + } + }} diff --git a/src/AElf.Client/AElfClientConstants.cs b/src/AElf.Client/AElfClientConstants.cs index 6c1efc9..4b99680 100644 --- a/src/AElf.Client/AElfClientConstants.cs +++ b/src/AElf.Client/AElfClientConstants.cs @@ -1,13 +1,14 @@ -namespace AElf.Client; - -public class AElfClientConstants +namespace AElf.Client { - public const string DefaultPrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; - public const string LocalEndpoint = "http://127.0.0.1:1235"; - public const string MainNetMainChain = "https://aelf-public-node.aelf.io"; - public const string MainNetSidechain = "https://tdvv-public-node.aelf.io"; - public const string TestNetMainChain = "https://aelf-test-node.aelf.io"; - public const string TestNetSidechain = "https://tdvv-test-node.aelf.io"; - public const int MainChainId = 9992731; - public const int SidechainId = 9992731; -} \ No newline at end of file + + public class AElfClientConstants + { + public const string DefaultPrivateKey = "09da44778f8db2e602fb484334f37df19e221c84c4582ce5b7770ccfbc3ddbef"; + public const string LocalEndpoint = "http://127.0.0.1:1235"; + public const string MainNetMainChain = "https://aelf-public-node.aelf.io"; + public const string MainNetSidechain = "https://tdvv-public-node.aelf.io"; + public const string TestNetMainChain = "https://aelf-test-node.aelf.io"; + public const string TestNetSidechain = "https://tdvv-test-node.aelf.io"; + public const int MainChainId = 9992731; + public const int SidechainId = 9992731; + }} diff --git a/src/AElf.Client/Dto/BlockBodyDto.cs b/src/AElf.Client/Dto/BlockBodyDto.cs index e2832e3..0a880b4 100644 --- a/src/AElf.Client/Dto/BlockBodyDto.cs +++ b/src/AElf.Client/Dto/BlockBodyDto.cs @@ -1,8 +1,11 @@ -namespace AElf.Client.Dto; +using System.Collections.Generic; -public class BlockBodyDto +namespace AElf.Client.Dto { - public int TransactionsCount { get; set; } - - public List Transactions { get; set; } -} \ No newline at end of file + + public class BlockBodyDto + { + public int TransactionsCount { get; set; } + + public List Transactions { get; set; } + }} diff --git a/src/AElf.Client/Dto/BlockDto.cs b/src/AElf.Client/Dto/BlockDto.cs index 2c25367..0ae41ea 100644 --- a/src/AElf.Client/Dto/BlockDto.cs +++ b/src/AElf.Client/Dto/BlockDto.cs @@ -1,10 +1,11 @@ -namespace AElf.Client.Dto; - -public class BlockDto +namespace AElf.Client.Dto { - public string BlockHash { get; set; } - - public BlockHeaderDto Header { get; set; } - - public BlockBodyDto Body { get; set; } -} \ No newline at end of file + + public class BlockDto + { + public string BlockHash { get; set; } + + public BlockHeaderDto Header { get; set; } + + public BlockBodyDto Body { get; set; } + }} diff --git a/src/AElf.Client/Dto/BlockHeaderDto.cs b/src/AElf.Client/Dto/BlockHeaderDto.cs index 699ff94..2740608 100644 --- a/src/AElf.Client/Dto/BlockHeaderDto.cs +++ b/src/AElf.Client/Dto/BlockHeaderDto.cs @@ -1,24 +1,27 @@ -namespace AElf.Client.Dto; +using System; -public class BlockHeaderDto +namespace AElf.Client.Dto { - public string PreviousBlockHash { get; set; } - - public string MerkleTreeRootOfTransactions { get; set; } - - public string MerkleTreeRootOfWorldState { get; set; } - - public string MerkleTreeRootOfTransactionState { get; set; } - - public string Extra { get; set; } - - public long Height { get; set; } - - public DateTime Time { get; set; } - - public string ChainId { get; set; } - - public string Bloom { get; set; } - - public string SignerPubkey { get; set; } -} \ No newline at end of file + + public class BlockHeaderDto + { + public string PreviousBlockHash { get; set; } + + public string MerkleTreeRootOfTransactions { get; set; } + + public string MerkleTreeRootOfWorldState { get; set; } + + public string MerkleTreeRootOfTransactionState { get; set; } + + public string Extra { get; set; } + + public long Height { get; set; } + + public DateTime Time { get; set; } + + public string ChainId { get; set; } + + public string Bloom { get; set; } + + public string SignerPubkey { get; set; } + }} diff --git a/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs b/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs index 248f4c1..283c1ae 100644 --- a/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs +++ b/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs @@ -1,6 +1,7 @@ -namespace AElf.Client.Dto; - -public class CalculateTransactionFeeInput +namespace AElf.Client.Dto { - public string RawTransaction { get; set; } -} \ No newline at end of file + + public class CalculateTransactionFeeInput + { + public string RawTransaction { get; set; } + }} diff --git a/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs b/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs index cb79c6c..26e80cc 100644 --- a/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs +++ b/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs @@ -1,11 +1,14 @@ -namespace AElf.Client.Dto; +using System.Collections.Generic; -public class CalculateTransactionFeeOutput +namespace AElf.Client.Dto { - - public bool Success { get; set; } - - public Dictionary TransactionFee { get; set; } - - public Dictionary ResourceFee { get; set; } -} \ No newline at end of file + + public class CalculateTransactionFeeOutput + { + + public bool Success { get; set; } + + public Dictionary TransactionFee { get; set; } + + public Dictionary ResourceFee { get; set; } + }} diff --git a/src/AElf.Client/Dto/ChainStatusDto.cs b/src/AElf.Client/Dto/ChainStatusDto.cs index 2cb6580..5b02c00 100644 --- a/src/AElf.Client/Dto/ChainStatusDto.cs +++ b/src/AElf.Client/Dto/ChainStatusDto.cs @@ -1,26 +1,29 @@ -namespace AElf.Client.Dto; +using System.Collections.Generic; -public class ChainStatusDto +namespace AElf.Client.Dto { - public string ChainId { get; set; } - - public Dictionary Branches { get; set; } - - public Dictionary NotLinkedBlocks { get; set; } - - public long LongestChainHeight { get; set; } - - public string LongestChainHash { get; set; } - - public string GenesisBlockHash { get; set; } - - public string GenesisContractAddress { get; set; } - - public string LastIrreversibleBlockHash { get; set; } - - public long LastIrreversibleBlockHeight { get; set; } - - public string BestChainHash { get; set; } - - public long BestChainHeight { get; set; } -} \ No newline at end of file + + public class ChainStatusDto + { + public string ChainId { get; set; } + + public Dictionary Branches { get; set; } + + public Dictionary NotLinkedBlocks { get; set; } + + public long LongestChainHeight { get; set; } + + public string LongestChainHash { get; set; } + + public string GenesisBlockHash { get; set; } + + public string GenesisContractAddress { get; set; } + + public string LastIrreversibleBlockHash { get; set; } + + public long LastIrreversibleBlockHeight { get; set; } + + public string BestChainHash { get; set; } + + public long BestChainHeight { get; set; } + }} diff --git a/src/AElf.Client/Dto/CreateRawTransactionInput.cs b/src/AElf.Client/Dto/CreateRawTransactionInput.cs index ee21c92..02d2519 100644 --- a/src/AElf.Client/Dto/CreateRawTransactionInput.cs +++ b/src/AElf.Client/Dto/CreateRawTransactionInput.cs @@ -1,78 +1,35 @@ -using System.ComponentModel.DataAnnotations; - -namespace AElf.Client.Dto; - -public class CreateRawTransactionInput : IValidatableObject +namespace AElf.Client.Dto { - /// - /// from address - /// - [Required] - public string From { get; set; } - - /// - /// to address - /// - [Required] - public string To { get; set; } - - /// - /// refer block height - /// - [Required] - public long RefBlockNumber { get; set; } - - /// - /// refer block hash - /// - [Required] - public string RefBlockHash { get; set; } - - /// - /// contract method name - /// - [Required] - public string MethodName { get; set; } - - /// - /// contract method parameters - /// - [Required] - public string Params { get; set; } - - public IEnumerable Validate(ValidationContext validationContext) + public class CreateRawTransactionInput { - var validationResults = new List(); - try - { - Address.FromBase58(From); - } - catch - { - validationResults.Add(new ValidationResult(Error.Message[Error.InvalidAddress], - new[] {nameof(From)})); - } - - try - { - Address.FromBase58(To); - } - catch - { - validationResults.Add( - new ValidationResult(Error.Message[Error.InvalidAddress], new[] {nameof(To)})); - } - - try - { - Hash.LoadFromHex(RefBlockHash); - } - catch - { - validationResults.Add( - new ValidationResult(Error.Message[Error.InvalidBlockHash], new[] {nameof(RefBlockHash)})); - } - - return validationResults; + /// + /// from address + /// + public string From { get; set; } + + /// + /// to address + /// + public string To { get; set; } + + /// + /// refer block height + /// + public long RefBlockNumber { get; set; } + + /// + /// refer block hash + /// + public string RefBlockHash { get; set; } + + /// + /// contract method name + /// + public string MethodName { get; set; } + + /// + /// contract method parameters + /// + public string Params { get; set; } } } \ No newline at end of file diff --git a/src/AElf.Client/Dto/CreateRawTransactionOutput.cs b/src/AElf.Client/Dto/CreateRawTransactionOutput.cs index 7896ec8..ead5fb7 100644 --- a/src/AElf.Client/Dto/CreateRawTransactionOutput.cs +++ b/src/AElf.Client/Dto/CreateRawTransactionOutput.cs @@ -1,6 +1,7 @@ -namespace AElf.Client.Dto; - -public class CreateRawTransactionOutput +namespace AElf.Client.Dto { - public string RawTransaction { get; set; } -} \ No newline at end of file + + public class CreateRawTransactionOutput + { + public string RawTransaction { get; set; } + }} diff --git a/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs b/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs index b07cd89..23c70fc 100644 --- a/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs +++ b/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs @@ -1,14 +1,15 @@ -namespace AElf.Client.Dto; - -public class ExecuteRawTransactionDto +namespace AElf.Client.Dto { - /// - /// raw transaction - /// - public string RawTransaction { get; set; } - - /// - /// signature - /// - public string Signature { get; set; } -} \ No newline at end of file + + public class ExecuteRawTransactionDto + { + /// + /// raw transaction + /// + public string RawTransaction { get; set; } + + /// + /// signature + /// + public string Signature { get; set; } + }} diff --git a/src/AElf.Client/Dto/ExecuteTransactionDto.cs b/src/AElf.Client/Dto/ExecuteTransactionDto.cs index 5ee6279..dc8b784 100644 --- a/src/AElf.Client/Dto/ExecuteTransactionDto.cs +++ b/src/AElf.Client/Dto/ExecuteTransactionDto.cs @@ -1,9 +1,10 @@ -namespace AElf.Client.Dto; - -public class ExecuteTransactionDto +namespace AElf.Client.Dto { - /// - /// raw transaction - /// - public string RawTransaction { get; set; } -} \ No newline at end of file + + public class ExecuteTransactionDto + { + /// + /// raw transaction + /// + public string RawTransaction { get; set; } + }} diff --git a/src/AElf.Client/Dto/LogEventDto.cs b/src/AElf.Client/Dto/LogEventDto.cs index 74dfd09..f7a2560 100644 --- a/src/AElf.Client/Dto/LogEventDto.cs +++ b/src/AElf.Client/Dto/LogEventDto.cs @@ -1,12 +1,13 @@ -namespace AElf.Client.Dto; - -public class LogEventDto +namespace AElf.Client.Dto { - public string Address { get; set; } - - public string Name { get; set; } - - public string[] Indexed { get; set; } - - public string NonIndexed { get; set; } -} \ No newline at end of file + + public class LogEventDto + { + public string Address { get; set; } + + public string Name { get; set; } + + public string[] Indexed { get; set; } + + public string NonIndexed { get; set; } + }} diff --git a/src/AElf.Client/Dto/MerklePathDto.cs b/src/AElf.Client/Dto/MerklePathDto.cs index ee0f9d1..6bfe0b3 100644 --- a/src/AElf.Client/Dto/MerklePathDto.cs +++ b/src/AElf.Client/Dto/MerklePathDto.cs @@ -1,12 +1,15 @@ -namespace AElf.Client.Dto; +using System.Collections.Generic; -public class MerklePathDto +namespace AElf.Client.Dto { - public List MerklePathNodes; -} - -public class MerklePathNodeDto -{ - public string Hash { get; set; } - public bool IsLeftChildNode { get; set; } -} \ No newline at end of file + + public class MerklePathDto + { + public List MerklePathNodes; + } + + public class MerklePathNodeDto + { + public string Hash { get; set; } + public bool IsLeftChildNode { get; set; } + }} diff --git a/src/AElf.Client/Dto/NetworkInfoOutput.cs b/src/AElf.Client/Dto/NetworkInfoOutput.cs index 50f76a5..5d95ecb 100644 --- a/src/AElf.Client/Dto/NetworkInfoOutput.cs +++ b/src/AElf.Client/Dto/NetworkInfoOutput.cs @@ -1,19 +1,20 @@ -namespace AElf.Client.Dto; - -public class NetworkInfoOutput +namespace AElf.Client.Dto { - /// - /// node version - /// - public string Version { get; set; } - - /// - /// network protocol version - /// - public int ProtocolVersion { get; set; } - - /// - /// total number of open connections between this node and other nodes - /// - public int Connections { get; set; } -} \ No newline at end of file + + public class NetworkInfoOutput + { + /// + /// node version + /// + public string Version { get; set; } + + /// + /// network protocol version + /// + public int ProtocolVersion { get; set; } + + /// + /// total number of open connections between this node and other nodes + /// + public int Connections { get; set; } + }} diff --git a/src/AElf.Client/Dto/PeerDto.cs b/src/AElf.Client/Dto/PeerDto.cs index 69e4149..16a3764 100644 --- a/src/AElf.Client/Dto/PeerDto.cs +++ b/src/AElf.Client/Dto/PeerDto.cs @@ -1,23 +1,26 @@ -namespace AElf.Client.Dto; +using System.Collections.Generic; -public class PeerDto +namespace AElf.Client.Dto { - public string IpAddress { get; set; } - public int ProtocolVersion { get; set; } - public long ConnectionTime { get; set; } - public string ConnectionStatus { get; set; } - public bool Inbound { get; set; } - public int BufferedTransactionsCount { get; set; } - public int BufferedBlocksCount { get; set; } - public int BufferedAnnouncementsCount { get; set; } - public List RequestMetrics { get; set; } - public string NodeVersion { get; set; } -} - -public class RequestMetric -{ - public long RoundTripTime { get; set; } - public string MethodName { get; set; } - public string Info { get; set; } - public string RequestTime { get; set; } -} \ No newline at end of file + + public class PeerDto + { + public string IpAddress { get; set; } + public int ProtocolVersion { get; set; } + public long ConnectionTime { get; set; } + public string ConnectionStatus { get; set; } + public bool Inbound { get; set; } + public int BufferedTransactionsCount { get; set; } + public int BufferedBlocksCount { get; set; } + public int BufferedAnnouncementsCount { get; set; } + public List RequestMetrics { get; set; } + public string NodeVersion { get; set; } + } + + public class RequestMetric + { + public long RoundTripTime { get; set; } + public string MethodName { get; set; } + public string Info { get; set; } + public string RequestTime { get; set; } + }} diff --git a/src/AElf.Client/Dto/SendRawTransactionInput.cs b/src/AElf.Client/Dto/SendRawTransactionInput.cs index e5941ec..747c8cc 100644 --- a/src/AElf.Client/Dto/SendRawTransactionInput.cs +++ b/src/AElf.Client/Dto/SendRawTransactionInput.cs @@ -1,19 +1,20 @@ -namespace AElf.Client.Dto; - -public class SendRawTransactionInput +namespace AElf.Client.Dto { - /// - /// raw transaction - /// - public string Transaction { get; set; } - - /// - /// signature - /// - public string Signature { get; set; } - - /// - /// return transaction detail or not - /// - public bool ReturnTransaction { get; set; } -} \ No newline at end of file + + public class SendRawTransactionInput + { + /// + /// raw transaction + /// + public string Transaction { get; set; } + + /// + /// signature + /// + public string Signature { get; set; } + + /// + /// return transaction detail or not + /// + public bool ReturnTransaction { get; set; } + }} diff --git a/src/AElf.Client/Dto/SendRawTransactionOutput.cs b/src/AElf.Client/Dto/SendRawTransactionOutput.cs index 25046c8..947fa1d 100644 --- a/src/AElf.Client/Dto/SendRawTransactionOutput.cs +++ b/src/AElf.Client/Dto/SendRawTransactionOutput.cs @@ -1,8 +1,9 @@ -namespace AElf.Client.Dto; - -public class SendRawTransactionOutput +namespace AElf.Client.Dto { - public string TransactionId { get; set; } - - public TransactionDto Transaction { get; set; } -} \ No newline at end of file + + public class SendRawTransactionOutput + { + public string TransactionId { get; set; } + + public TransactionDto Transaction { get; set; } + }} diff --git a/src/AElf.Client/Dto/SendTransactionInput.cs b/src/AElf.Client/Dto/SendTransactionInput.cs index 1e1c8cc..0f2e8a4 100644 --- a/src/AElf.Client/Dto/SendTransactionInput.cs +++ b/src/AElf.Client/Dto/SendTransactionInput.cs @@ -1,9 +1,10 @@ -namespace AElf.Client.Dto; - -public class SendTransactionInput +namespace AElf.Client.Dto { - /// - /// raw transaction - /// - public string RawTransaction { get; set; } -} \ No newline at end of file + + public class SendTransactionInput + { + /// + /// raw transaction + /// + public string RawTransaction { get; set; } + }} diff --git a/src/AElf.Client/Dto/SendTransactionOutput.cs b/src/AElf.Client/Dto/SendTransactionOutput.cs index f22ca67..4a9e688 100644 --- a/src/AElf.Client/Dto/SendTransactionOutput.cs +++ b/src/AElf.Client/Dto/SendTransactionOutput.cs @@ -1,6 +1,7 @@ -namespace AElf.Client.Dto; - -public class SendTransactionOutput +namespace AElf.Client.Dto { - public string TransactionId { get; set; } -} \ No newline at end of file + + public class SendTransactionOutput + { + public string TransactionId { get; set; } + }} diff --git a/src/AElf.Client/Dto/SendTransactionsInput.cs b/src/AElf.Client/Dto/SendTransactionsInput.cs index c623c74..629ae73 100644 --- a/src/AElf.Client/Dto/SendTransactionsInput.cs +++ b/src/AElf.Client/Dto/SendTransactionsInput.cs @@ -1,9 +1,10 @@ -namespace AElf.Client.Dto; - -public class SendTransactionsInput +namespace AElf.Client.Dto { - /// - /// raw transactions - /// - public string RawTransactions { get; set; } -} \ No newline at end of file + + public class SendTransactionsInput + { + /// + /// raw transactions + /// + public string RawTransactions { get; set; } + }} diff --git a/src/AElf.Client/Dto/TaskQueueInfoDto.cs b/src/AElf.Client/Dto/TaskQueueInfoDto.cs index d02fc56..15b1f79 100644 --- a/src/AElf.Client/Dto/TaskQueueInfoDto.cs +++ b/src/AElf.Client/Dto/TaskQueueInfoDto.cs @@ -1,8 +1,9 @@ -namespace AElf.Client.Dto; - -public class TaskQueueInfoDto +namespace AElf.Client.Dto { - public string Name { get; set; } - - public int Size { get; set; } -} \ No newline at end of file + + public class TaskQueueInfoDto + { + public string Name { get; set; } + + public int Size { get; set; } + }} diff --git a/src/AElf.Client/Dto/TransactionDto.cs b/src/AElf.Client/Dto/TransactionDto.cs index fbfc40d..1f5147e 100644 --- a/src/AElf.Client/Dto/TransactionDto.cs +++ b/src/AElf.Client/Dto/TransactionDto.cs @@ -1,18 +1,19 @@ -namespace AElf.Client.Dto; - -public class TransactionDto +namespace AElf.Client.Dto { - public string From { get; set; } - - public string To { get; set; } - - public long RefBlockNumber { get; set; } - - public string RefBlockPrefix { get; set; } - - public string MethodName { get; set; } - - public string Params { get; set; } - - public string Signature { get; set; } -} \ No newline at end of file + + public class TransactionDto + { + public string From { get; set; } + + public string To { get; set; } + + public long RefBlockNumber { get; set; } + + public string RefBlockPrefix { get; set; } + + public string MethodName { get; set; } + + public string Params { get; set; } + + public string Signature { get; set; } + }} diff --git a/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs b/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs index ba60b96..c214654 100644 --- a/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs +++ b/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs @@ -1,7 +1,8 @@ -namespace AElf.Client.Dto; - -public class TransactionPoolStatusOutput +namespace AElf.Client.Dto { - public int Queued { get; set; } - public int Validated { get; set; } -} \ No newline at end of file + + public class TransactionPoolStatusOutput + { + public int Queued { get; set; } + public int Validated { get; set; } + }} diff --git a/src/AElf.Client/Dto/TransactionResultDto.cs b/src/AElf.Client/Dto/TransactionResultDto.cs index 30ff3fa..355e5e8 100644 --- a/src/AElf.Client/Dto/TransactionResultDto.cs +++ b/src/AElf.Client/Dto/TransactionResultDto.cs @@ -1,22 +1,23 @@ -namespace AElf.Client.Dto; - -public class TransactionResultDto +namespace AElf.Client.Dto { - public string TransactionId { get; set; } - - public string Status { get; set; } - - public LogEventDto[] Logs { get; set; } - - public string Bloom { get; set; } - - public long BlockNumber { get; set; } - - public string BlockHash { get; set; } - - public TransactionDto Transaction { get; set; } - - public string ReturnValue { get; set; } - - public string Error { get; set; } -} \ No newline at end of file + + public class TransactionResultDto + { + public string TransactionId { get; set; } + + public string Status { get; set; } + + public LogEventDto[] Logs { get; set; } + + public string Bloom { get; set; } + + public long BlockNumber { get; set; } + + public string BlockHash { get; set; } + + public TransactionDto Transaction { get; set; } + + public string ReturnValue { get; set; } + + public string Error { get; set; } + }} diff --git a/src/AElf.Client/EndpointType.cs b/src/AElf.Client/EndpointType.cs index 0b132fa..67d0148 100644 --- a/src/AElf.Client/EndpointType.cs +++ b/src/AElf.Client/EndpointType.cs @@ -1,10 +1,11 @@ -namespace AElf.Client; - -public enum EndpointType +namespace AElf.Client { - MainNetMainChain, - MainNetSidechain, - TestNetMainChain, - TestNetSidechain, - Local -} \ No newline at end of file + + public enum EndpointType + { + MainNetMainChain, + MainNetSidechain, + TestNetMainChain, + TestNetSidechain, + Local + }} diff --git a/src/AElf.Client/Exception/AElfClientException.cs b/src/AElf.Client/Exception/AElfClientException.cs index 1f9c409..13475d7 100644 --- a/src/AElf.Client/Exception/AElfClientException.cs +++ b/src/AElf.Client/Exception/AElfClientException.cs @@ -1,9 +1,12 @@ -namespace AElf.Client; +using System; -public class AElfClientException : Exception +namespace AElf.Client { - public AElfClientException(string message) : base(message) + + public class AElfClientException : Exception { - - } -} \ No newline at end of file + public AElfClientException(string message) : base(message) + { + + } + }} diff --git a/src/AElf.Client/Exception/Error.cs b/src/AElf.Client/Exception/Error.cs index fc78fc6..33cae9e 100644 --- a/src/AElf.Client/Exception/Error.cs +++ b/src/AElf.Client/Exception/Error.cs @@ -1,35 +1,38 @@ -namespace AElf.Client; +using System.Collections.Generic; -public class Error +namespace AElf.Client { - public const int NotFound = 20001; - public const int InvalidAddress = 20002; - public const int InvalidBlockHash = 20003; - public const int InvalidTransactionId = 20004; - public const int InvalidProposalId = 20005; - public const int InvalidOffset = 20006; - public const int InvalidLimit = 20007; - public const int InvalidTransaction = 20008; - public const int CannotBroadcastTransaction = 20009; - public const int InvalidContractAddress = 20010; - public const int NoMatchMethodInContractAddress = 20011; - public const int InvalidParams = 20012; - public const int InvalidSignature = 20013; - - public static readonly Dictionary Message = new Dictionary + + public class Error { - {NotFound, "Not found"}, - {InvalidAddress, "Invalid address format"}, - {InvalidBlockHash, "Invalid block hash format"}, - {InvalidTransactionId, "Invalid Transaction id format"}, - {InvalidProposalId, "Invalid proposal id format"}, - {InvalidOffset, "Offset must greater than or equal to 0"}, - {InvalidLimit, "Limit must between 0 and 100"}, - {InvalidTransaction, "Invalid transaction information"}, - {CannotBroadcastTransaction, "Sync still in progress, cannot send transactions"}, - {InvalidContractAddress, "Invalid contract address"}, - {NoMatchMethodInContractAddress, "No match method in contract address"}, - {InvalidParams, "Invalid params"}, - {InvalidSignature, "Invalid signature"} - }; -} \ No newline at end of file + public const int NotFound = 20001; + public const int InvalidAddress = 20002; + public const int InvalidBlockHash = 20003; + public const int InvalidTransactionId = 20004; + public const int InvalidProposalId = 20005; + public const int InvalidOffset = 20006; + public const int InvalidLimit = 20007; + public const int InvalidTransaction = 20008; + public const int CannotBroadcastTransaction = 20009; + public const int InvalidContractAddress = 20010; + public const int NoMatchMethodInContractAddress = 20011; + public const int InvalidParams = 20012; + public const int InvalidSignature = 20013; + + public static readonly Dictionary Message = new Dictionary + { + {NotFound, "Not found"}, + {InvalidAddress, "Invalid address format"}, + {InvalidBlockHash, "Invalid block hash format"}, + {InvalidTransactionId, "Invalid Transaction id format"}, + {InvalidProposalId, "Invalid proposal id format"}, + {InvalidOffset, "Offset must greater than or equal to 0"}, + {InvalidLimit, "Limit must between 0 and 100"}, + {InvalidTransaction, "Invalid transaction information"}, + {CannotBroadcastTransaction, "Sync still in progress, cannot send transactions"}, + {InvalidContractAddress, "Invalid contract address"}, + {NoMatchMethodInContractAddress, "No match method in contract address"}, + {InvalidParams, "Invalid params"}, + {InvalidSignature, "Invalid signature"} + }; + }} diff --git a/src/AElf.Client/Extensions/StringExtensions.cs b/src/AElf.Client/Extensions/StringExtensions.cs index 7b2108f..891aaa8 100644 --- a/src/AElf.Client/Extensions/StringExtensions.cs +++ b/src/AElf.Client/Extensions/StringExtensions.cs @@ -1,14 +1,17 @@ -namespace AElf.Client.Extensions; +using AElf.Types; -public static class StringExtensions +namespace AElf.Client.Extensions { - public static Address ToAddress(this string? address) + + public static class StringExtensions { - if (address == null) + public static Address ToAddress(this string? address) { - return Address.FromPublicKey(ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey)); + if (address == null) + { + return Address.FromPublicKey(ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey)); + } + + return Address.FromBase58(address); } - - return Address.FromBase58(address); - } -} \ No newline at end of file + }} diff --git a/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs b/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs index 886aaaa..8701bee 100644 --- a/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs +++ b/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs @@ -1,37 +1,40 @@ +using System.Collections.Generic; +using System.Linq; using AElf.Client.Dto; using AElf.Contracts.MultiToken; using Google.Protobuf; -namespace AElf.Client.Extensions; - -public static class TransactionResultDtoExtension +namespace AElf.Client.Extensions { - public static Dictionary GetTransactionFees(this TransactionResultDto transactionResultDto) + + public static class TransactionResultDtoExtension { - var result = new Dictionary(); - - var transactionFeeLogs = - transactionResultDto.Logs?.Where(l => l.Name == nameof(TransactionFeeCharged)).ToList(); - if (transactionFeeLogs != null) + public static Dictionary GetTransactionFees(this TransactionResultDto transactionResultDto) { - foreach (var transactionFee in transactionFeeLogs.Select(transactionFeeLog => - TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) + var result = new Dictionary(); + + var transactionFeeLogs = + transactionResultDto.Logs?.Where(l => l.Name == nameof(TransactionFeeCharged)).ToList(); + if (transactionFeeLogs != null) { - result.Add(transactionFee.Symbol, transactionFee.Amount); + foreach (var transactionFee in transactionFeeLogs.Select(transactionFeeLog => + TransactionFeeCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) + { + result.Add(transactionFee.Symbol, transactionFee.Amount); + } } - } - - var resourceTokenLogs = - transactionResultDto.Logs?.Where(l => l.Name == nameof(ResourceTokenCharged)).ToList(); - if (resourceTokenLogs != null) - { - foreach (var resourceToken in resourceTokenLogs.Select(transactionFeeLog => - ResourceTokenCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) + + var resourceTokenLogs = + transactionResultDto.Logs?.Where(l => l.Name == nameof(ResourceTokenCharged)).ToList(); + if (resourceTokenLogs != null) { - result.Add(resourceToken.Symbol, resourceToken.Amount); + foreach (var resourceToken in resourceTokenLogs.Select(transactionFeeLog => + ResourceTokenCharged.Parser.ParseFrom(ByteString.FromBase64(transactionFeeLog.NonIndexed)))) + { + result.Add(resourceToken.Symbol, resourceToken.Amount); + } } + + return result; } - - return result; - } -} \ No newline at end of file + }} diff --git a/src/AElf.Client/GlobalUsings.cs b/src/AElf.Client/GlobalUsings.cs deleted file mode 100644 index e2e7f5c..0000000 --- a/src/AElf.Client/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using AElf.Types; \ No newline at end of file diff --git a/src/AElf.Client/Services/HttpService.cs b/src/AElf.Client/Services/HttpService.cs index 74bbdde..34f364a 100644 --- a/src/AElf.Client/Services/HttpService.cs +++ b/src/AElf.Client/Services/HttpService.cs @@ -7,209 +7,210 @@ using System.Text.Json; using System.Threading.Tasks; -namespace AElf.Client.Service; - -public interface IHttpService -{ - Task GetResponseAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK); - - Task PostResponseAsync(string url, Dictionary parameters, - string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue? authenticationHeaderValue = null); - - Task DeleteResponseAsObjectAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null); -} - -public class HttpService : IHttpService +namespace AElf.Client.Service { - private HttpClient Client { get; set; } - private int TimeoutSeconds { get; } - - public HttpService(int timeoutSeconds) - { - TimeoutSeconds = timeoutSeconds; - } - - /// - /// Get request. - /// - /// - /// - /// - /// - /// - public async Task GetResponseAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) - { - var response = await GetResponseAsync(url, version, expectedStatusCode); - var stream = await response.Content.ReadAsStreamAsync(); - return await JsonSerializer.DeserializeAsync(stream); - } - - /// - /// Post request. - /// - /// - /// - /// - /// - /// - /// - /// - public async Task PostResponseAsync(string url, Dictionary parameters, - string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue? authenticationHeaderValue = null) + + public interface IHttpService { - var response = await PostResponseAsync(url, parameters, version, true, expectedStatusCode, - authenticationHeaderValue); - var stream = await response.Content.ReadAsStreamAsync(); - return await JsonSerializer.DeserializeAsync(stream); + Task GetResponseAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK); + + Task PostResponseAsync(string url, Dictionary parameters, + string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue? authenticationHeaderValue = null); + + Task DeleteResponseAsObjectAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null); } - - /// - /// Delete request. - /// - /// - /// - /// - /// - /// - /// - public async Task DeleteResponseAsObjectAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null) - { - var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); - var stream = await response.Content.ReadAsStreamAsync(); - return await JsonSerializer.DeserializeAsync(stream); - } - - #region GetResponse - - private async Task GetResponseAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) + + public class HttpService : IHttpService { - version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; - - var client = GetHttpClient(version); - try + private HttpClient Client { get; set; } + private int TimeoutSeconds { get; } + + public HttpService(int timeoutSeconds) { - var response = await client.GetAsync(url); - if (response.StatusCode == expectedStatusCode) - return response; - throw new AElfClientException(response.ToString()); + TimeoutSeconds = timeoutSeconds; } - catch (Exception ex) + + /// + /// Get request. + /// + /// + /// + /// + /// + /// + public async Task GetResponseAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK) { - throw new AElfClientException(ex.Message); + var response = await GetResponseAsync(url, version, expectedStatusCode); + var stream = await response.Content.ReadAsStreamAsync(); + return await JsonSerializer.DeserializeAsync(stream); } - } - - #endregion - - #region PostResponse - - private async Task PostResponseAsync(string url, - Dictionary parameters, - string? version = null, bool useApplicationJson = false, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue? authenticationHeaderValue = null) - { - version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; - var client = GetHttpClient(version); - - if (authenticationHeaderValue != null) + + /// + /// Post request. + /// + /// + /// + /// + /// + /// + /// + /// + public async Task PostResponseAsync(string url, Dictionary parameters, + string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue? authenticationHeaderValue = null) { - client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; + var response = await PostResponseAsync(url, parameters, version, true, expectedStatusCode, + authenticationHeaderValue); + var stream = await response.Content.ReadAsStreamAsync(); + return await JsonSerializer.DeserializeAsync(stream); } - - HttpContent content; - if (useApplicationJson) + + /// + /// Delete request. + /// + /// + /// + /// + /// + /// + /// + public async Task DeleteResponseAsObjectAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) { - var paramsStr = JsonSerializer.Serialize(parameters); - content = new StringContent(paramsStr, Encoding.UTF8, "application/json"); - content.Headers.ContentType = MediaTypeHeaderValue.Parse($"application/json{version}"); + var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); + var stream = await response.Content.ReadAsStreamAsync(); + return await JsonSerializer.DeserializeAsync(stream); } - - else + + #region GetResponse + + private async Task GetResponseAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK) { - content = new FormUrlEncodedContent(parameters); - content.Headers.ContentType = - MediaTypeHeaderValue.Parse($"application/x-www-form-urlencoded{version}"); + version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; + + var client = GetHttpClient(version); + try + { + var response = await client.GetAsync(url); + if (response.StatusCode == expectedStatusCode) + return response; + throw new AElfClientException(response.ToString()); + } + catch (Exception ex) + { + throw new AElfClientException(ex.Message); + } } - - try + + #endregion + + #region PostResponse + + private async Task PostResponseAsync(string url, + Dictionary parameters, + string? version = null, bool useApplicationJson = false, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue? authenticationHeaderValue = null) { - var response = await client.PostAsync(url, content); - if (response.StatusCode == expectedStatusCode) - return response; - var message = await response.Content.ReadAsStringAsync(); - throw new HttpRequestException(message); + version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; + var client = GetHttpClient(version); + + if (authenticationHeaderValue != null) + { + client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; + } + + HttpContent content; + if (useApplicationJson) + { + var paramsStr = JsonSerializer.Serialize(parameters); + content = new StringContent(paramsStr, Encoding.UTF8, "application/json"); + content.Headers.ContentType = MediaTypeHeaderValue.Parse($"application/json{version}"); + } + + else + { + content = new FormUrlEncodedContent(parameters); + content.Headers.ContentType = + MediaTypeHeaderValue.Parse($"application/x-www-form-urlencoded{version}"); + } + + try + { + var response = await client.PostAsync(url, content); + if (response.StatusCode == expectedStatusCode) + return response; + var message = await response.Content.ReadAsStringAsync(); + throw new HttpRequestException(message); + } + catch (Exception ex) + { + throw new AElfClientException(ex.Message); + } } - catch (Exception ex) + + #endregion + + #region DeleteResponse + + private async Task DeleteResponseAsStringAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) { - throw new AElfClientException(ex.Message); + var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); + return await response.Content.ReadAsStringAsync(); } - } - - #endregion - - #region DeleteResponse - - private async Task DeleteResponseAsStringAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null) - { - var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); - return await response.Content.ReadAsStringAsync(); - } - - private async Task DeleteResponseAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue authenticationHeaderValue = null) - { - version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; - var client = GetHttpClient(version); - - if (authenticationHeaderValue != null) + + private async Task DeleteResponseAsync(string url, string? version = null, + HttpStatusCode expectedStatusCode = HttpStatusCode.OK, + AuthenticationHeaderValue authenticationHeaderValue = null) { - client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; + version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; + var client = GetHttpClient(version); + + if (authenticationHeaderValue != null) + { + client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; + } + + try + { + var response = await client.DeleteAsync(url); + if (response.StatusCode == expectedStatusCode) + return response; + throw new AElfClientException(response.ToString()); + } + catch (Exception ex) + { + throw new AElfClientException(ex.Message); + } } - - try - { - var response = await client.DeleteAsync(url); - if (response.StatusCode == expectedStatusCode) - return response; - throw new AElfClientException(response.ToString()); - } - catch (Exception ex) + + #endregion + + #region private methods + + private HttpClient GetHttpClient(string? version = null) { - throw new AElfClientException(ex.Message); + if (Client != null) return Client; + Client = new HttpClient + { + Timeout = TimeSpan.FromSeconds(TimeoutSeconds) + }; + Client.DefaultRequestHeaders.Accept.Clear(); + Client.DefaultRequestHeaders.Accept.Add( + MediaTypeWithQualityHeaderValue.Parse($"application/json{version}")); + Client.DefaultRequestHeaders.Add("Connection", "close"); + return Client; } - } - - #endregion - - #region private methods - - private HttpClient GetHttpClient(string? version = null) - { - if (Client != null) return Client; - Client = new HttpClient - { - Timeout = TimeSpan.FromSeconds(TimeoutSeconds) - }; - Client.DefaultRequestHeaders.Accept.Clear(); - Client.DefaultRequestHeaders.Accept.Add( - MediaTypeWithQualityHeaderValue.Parse($"application/json{version}")); - Client.DefaultRequestHeaders.Add("Connection", "close"); - return Client; - } - - #endregion -} \ No newline at end of file + + #endregion + }} diff --git a/src/AElf.Client/Services/IBlockAppService.cs b/src/AElf.Client/Services/IBlockAppService.cs index ec449cf..1d5f9ae 100644 --- a/src/AElf.Client/Services/IBlockAppService.cs +++ b/src/AElf.Client/Services/IBlockAppService.cs @@ -1,12 +1,14 @@ +using System.Threading.Tasks; using AElf.Client.Dto; -namespace AElf.Client.Services; - -public interface IBlockAppService +namespace AElf.Client.Services { - Task GetBlockHeightAsync(); - - Task GetBlockByHashAsync(string blockHash, bool includeTransactions = false); - - Task GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false); -} \ No newline at end of file + + public interface IBlockAppService + { + Task GetBlockHeightAsync(); + + Task GetBlockByHashAsync(string blockHash, bool includeTransactions = false); + + Task GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false); + }} diff --git a/src/AElf.Client/Services/IChainAppService.cs b/src/AElf.Client/Services/IChainAppService.cs index 48d9b61..e149c32 100644 --- a/src/AElf.Client/Services/IChainAppService.cs +++ b/src/AElf.Client/Services/IChainAppService.cs @@ -1,15 +1,18 @@ +using System.Collections.Generic; +using System.Threading.Tasks; using AElf.Client.Dto; using AElf.Kernel; -namespace AElf.Client; - -public interface IChainAppService +namespace AElf.Client { - Task GetChainStatusAsync(); - - Task GetContractFileDescriptorSetAsync(string? address); - - Task> GetTaskQueueStatusAsync(); - - Task GetChainIdAsync(); -} \ No newline at end of file + + public interface IChainAppService + { + Task GetChainStatusAsync(); + + Task GetContractFileDescriptorSetAsync(string? address); + + Task> GetTaskQueueStatusAsync(); + + Task GetChainIdAsync(); + }} diff --git a/src/AElf.Client/Services/IClientService.cs b/src/AElf.Client/Services/IClientService.cs index 8331a7a..f97c7ab 100644 --- a/src/AElf.Client/Services/IClientService.cs +++ b/src/AElf.Client/Services/IClientService.cs @@ -1,13 +1,16 @@ +using System.Threading.Tasks; using AElf.Client.Model; +using AElf.Types; -namespace AElf.Client.Services; - -public interface IClientService +namespace AElf.Client.Services { - Task IsConnectedAsync(); - Task GetFormattedAddressAsync(Address address); - Task GetGenesisContractAddressAsync(); - Task
GetContractAddressByNameAsync(Hash contractNameHash); - string GetAddressFromPubKey(string pubKey); - KeyPairInfo GenerateKeyPairInfo(); -} \ No newline at end of file + + public interface IClientService + { + Task IsConnectedAsync(); + Task GetFormattedAddressAsync(Address address); + Task GetGenesisContractAddressAsync(); + Task
GetContractAddressByNameAsync(Hash contractNameHash); + string GetAddressFromPubKey(string pubKey); + KeyPairInfo GenerateKeyPairInfo(); + }} diff --git a/src/AElf.Client/Services/INetAppService.cs b/src/AElf.Client/Services/INetAppService.cs index ada9aea..c120aeb 100644 --- a/src/AElf.Client/Services/INetAppService.cs +++ b/src/AElf.Client/Services/INetAppService.cs @@ -1,14 +1,17 @@ +using System.Collections.Generic; +using System.Threading.Tasks; using AElf.Client.Dto; -namespace AElf.Client.Services; - -public interface INetAppService +namespace AElf.Client.Services { - Task AddPeerAsync(string ipAddress, string userName, string password); - - Task RemovePeerAsync(string ipAddress, string userName, string password); - - Task?> GetPeersAsync(bool withMetrics); - - Task GetNetworkInfoAsync(); -} \ No newline at end of file + + public interface INetAppService + { + Task AddPeerAsync(string ipAddress, string userName, string password); + + Task RemovePeerAsync(string ipAddress, string userName, string password); + + Task?> GetPeersAsync(bool withMetrics); + + Task GetNetworkInfoAsync(); + }} diff --git a/src/AElf.Client/Services/ITransactionAppService.cs b/src/AElf.Client/Services/ITransactionAppService.cs index 31f7ca0..e70a846 100644 --- a/src/AElf.Client/Services/ITransactionAppService.cs +++ b/src/AElf.Client/Services/ITransactionAppService.cs @@ -1,29 +1,32 @@ +using System.Collections.Generic; +using System.Threading.Tasks; using AElf.Client.Dto; -namespace AElf.Client.Services; - -public interface ITransactionAppService +namespace AElf.Client.Services { - Task GetTransactionPoolStatusAsync(); - - Task ExecuteTransactionAsync(ExecuteTransactionDto input); - - Task ExecuteRawTransactionAsync(ExecuteRawTransactionDto input); - - Task CreateRawTransactionAsync(CreateRawTransactionInput input); - - Task SendRawTransactionAsync(SendRawTransactionInput input); - - Task SendTransactionAsync(SendTransactionInput input); - - Task SendTransactionsAsync(SendTransactionsInput input); - - Task GetTransactionResultAsync(string transactionId); - - Task?> GetTransactionResultsAsync(string blockHash, int offset = 0, - int limit = 10); - - Task GetMerklePathByTransactionIdAsync(string transactionId); - - Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input); -} \ No newline at end of file + + public interface ITransactionAppService + { + Task GetTransactionPoolStatusAsync(); + + Task ExecuteTransactionAsync(ExecuteTransactionDto input); + + Task ExecuteRawTransactionAsync(ExecuteRawTransactionDto input); + + Task CreateRawTransactionAsync(CreateRawTransactionInput input); + + Task SendRawTransactionAsync(SendRawTransactionInput input); + + Task SendTransactionAsync(SendTransactionInput input); + + Task SendTransactionsAsync(SendTransactionsInput input); + + Task GetTransactionResultAsync(string transactionId); + + Task?> GetTransactionResultsAsync(string blockHash, int offset = 0, + int limit = 10); + + Task GetMerklePathByTransactionIdAsync(string transactionId); + + Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input); + }} diff --git a/src/AElf.Client/TransactionBuilder.cs b/src/AElf.Client/TransactionBuilder.cs index beb357f..4db766e 100644 --- a/src/AElf.Client/TransactionBuilder.cs +++ b/src/AElf.Client/TransactionBuilder.cs @@ -1,60 +1,62 @@ using AElf.Cryptography; +using AElf.Types; using Google.Protobuf; -namespace AElf.Client; - -public class TransactionBuilder +namespace AElf.Client { - private readonly AElfClient _aelfClient; - - private byte[] PrivateKey { get; set; } - private string ContractAddress { get; set; } - private string MethodName { get; set; } - private IMessage Parameter { get; set; } - - public TransactionBuilder(AElfClient aelfClient) - { - _aelfClient = aelfClient; - PrivateKey = ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey); - } - - public TransactionBuilder UsePrivateKey(byte[] privateKey) - { - PrivateKey = privateKey; - return this; - } - - public TransactionBuilder UseSystemContract(string systemContractName) - { - ContractAddress = _aelfClient.GetContractAddressByNameAsync(HashHelper.ComputeFrom(systemContractName)).Result - .ToBase58(); - return this; - } - - public TransactionBuilder UseContract(string contractAddress) - { - ContractAddress = contractAddress; - return this; - } - - public TransactionBuilder UseMethod(string methodName) - { - MethodName = methodName; - return this; - } - - public TransactionBuilder UseParameter(IMessage parameter) - { - Parameter = parameter; - return this; - } - - public Transaction Build() + + public class TransactionBuilder { - var keyPair = CryptoHelper.FromPrivateKey(PrivateKey); - var from = Address.FromPublicKey(keyPair.PublicKey).ToBase58(); - var unsignedTx = _aelfClient.GenerateTransactionAsync(from, ContractAddress, MethodName, Parameter).Result; - var signedTx = _aelfClient.SignTransaction(PrivateKey, unsignedTx); - return signedTx; - } -} \ No newline at end of file + private readonly AElfClient _aelfClient; + + private byte[] PrivateKey { get; set; } + private string ContractAddress { get; set; } + private string MethodName { get; set; } + private IMessage Parameter { get; set; } + + public TransactionBuilder(AElfClient aelfClient) + { + _aelfClient = aelfClient; + PrivateKey = ByteArrayHelper.HexStringToByteArray(AElfClientConstants.DefaultPrivateKey); + } + + public TransactionBuilder UsePrivateKey(byte[] privateKey) + { + PrivateKey = privateKey; + return this; + } + + public TransactionBuilder UseSystemContract(string systemContractName) + { + ContractAddress = _aelfClient.GetContractAddressByNameAsync(HashHelper.ComputeFrom(systemContractName)).Result + .ToBase58(); + return this; + } + + public TransactionBuilder UseContract(string contractAddress) + { + ContractAddress = contractAddress; + return this; + } + + public TransactionBuilder UseMethod(string methodName) + { + MethodName = methodName; + return this; + } + + public TransactionBuilder UseParameter(IMessage parameter) + { + Parameter = parameter; + return this; + } + + public Transaction Build() + { + var keyPair = CryptoHelper.FromPrivateKey(PrivateKey); + var from = Address.FromPublicKey(keyPair.PublicKey).ToBase58(); + var unsignedTx = _aelfClient.GenerateTransactionAsync(from, ContractAddress, MethodName, Parameter).Result; + var signedTx = _aelfClient.SignTransaction(PrivateKey, unsignedTx); + return signedTx; + } + }} From 6853f56b3d8fee7ca423cbdb3229f71d32ef4238 Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Wed, 28 Jun 2023 17:52:15 +0800 Subject: [PATCH 56/70] feat(HttpSerivce): replaced System.Text.Json with Newtonsoft.Json to reduce package dependency and incremented version number --- .../AElf.Client.Protobuf.csproj | 2 +- src/AElf.Client/AElf.Client.csproj | 2 +- src/AElf.Client/AElfClient.cs | 1 - src/AElf.Client/Services/HttpService.cs | 37 +++++++++++++++---- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj index 825d508..21e7c66 100644 --- a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj +++ b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj @@ -7,7 +7,7 @@ Protobuf using by AElf C# sdk. AElf true - 1.3.0 + 1.3.1 diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj index 3df80b7..ebf864c 100644 --- a/src/AElf.Client/AElf.Client.csproj +++ b/src/AElf.Client/AElf.Client.csproj @@ -7,7 +7,7 @@ This is a C# client library, used to communicate with the AElf API. AElf true - 1.3.0 + 1.3.1 9.0 diff --git a/src/AElf.Client/AElfClient.cs b/src/AElf.Client/AElfClient.cs index fdfc16a..90bbee0 100644 --- a/src/AElf.Client/AElfClient.cs +++ b/src/AElf.Client/AElfClient.cs @@ -1,5 +1,4 @@ using System; -using System.Text.Json; using AElf.Client.Service; namespace AElf.Client diff --git a/src/AElf.Client/Services/HttpService.cs b/src/AElf.Client/Services/HttpService.cs index 34f364a..280e385 100644 --- a/src/AElf.Client/Services/HttpService.cs +++ b/src/AElf.Client/Services/HttpService.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; +using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; -using System.Text.Json; using System.Threading.Tasks; +using Newtonsoft.Json; namespace AElf.Client.Service { @@ -46,8 +47,14 @@ public HttpService(int timeoutSeconds) HttpStatusCode expectedStatusCode = HttpStatusCode.OK) { var response = await GetResponseAsync(url, version, expectedStatusCode); - var stream = await response.Content.ReadAsStreamAsync(); - return await JsonSerializer.DeserializeAsync(stream); + await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + using var streamReader = new StreamReader(stream); + using var reader = new JsonTextReader(streamReader); + + var serializer = new JsonSerializer(); + var ret = serializer.Deserialize(reader); + + return ret; } /// @@ -67,8 +74,15 @@ public HttpService(int timeoutSeconds) { var response = await PostResponseAsync(url, parameters, version, true, expectedStatusCode, authenticationHeaderValue); - var stream = await response.Content.ReadAsStreamAsync(); - return await JsonSerializer.DeserializeAsync(stream); + + await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + using var streamReader = new StreamReader(stream); + using var reader = new JsonTextReader(streamReader); + + var serializer = new JsonSerializer(); + var ret = serializer.Deserialize(reader); + + return ret; } /// @@ -85,8 +99,15 @@ public HttpService(int timeoutSeconds) AuthenticationHeaderValue authenticationHeaderValue = null) { var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); - var stream = await response.Content.ReadAsStreamAsync(); - return await JsonSerializer.DeserializeAsync(stream); + + await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + using var streamReader = new StreamReader(stream); + using var reader = new JsonTextReader(streamReader); + + var serializer = new JsonSerializer(); + var ret = serializer.Deserialize(reader); + + return ret; } #region GetResponse @@ -131,7 +152,7 @@ private async Task PostResponseAsync(string url, HttpContent content; if (useApplicationJson) { - var paramsStr = JsonSerializer.Serialize(parameters); + var paramsStr = JsonConvert.SerializeObject(parameters); content = new StringContent(paramsStr, Encoding.UTF8, "application/json"); content.Headers.ContentType = MediaTypeHeaderValue.Parse($"application/json{version}"); } From b1df699c50cb5ba5f28100f125a6eeff9dd977c1 Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Mon, 3 Jul 2023 10:41:36 +0800 Subject: [PATCH 57/70] fix(AElf.Client.csproj): Added newtonsoft 13.0.3 instead of the old 10.0.0.0 assembly --- src/AElf.Client/AElf.Client.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj index ebf864c..4c774a6 100644 --- a/src/AElf.Client/AElf.Client.csproj +++ b/src/AElf.Client/AElf.Client.csproj @@ -7,7 +7,7 @@ This is a C# client library, used to communicate with the AElf API. AElf true - 1.3.1 + 1.3.2 9.0 @@ -18,7 +18,7 @@ - + From 7550b2705184c96387f230665b9238aa755d5e82 Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Sat, 15 Jul 2023 09:29:43 +0800 Subject: [PATCH 58/70] build(csproj): removed version and updated dependency version from Client and Client.Protobuf --- src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj | 3 +-- src/AElf.Client/AElf.Client.csproj | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj index 21e7c66..f3ec379 100644 --- a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj +++ b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj @@ -7,11 +7,10 @@ Protobuf using by AElf C# sdk. AElf true - 1.3.1 - + diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj index 4c774a6..c9bef7c 100644 --- a/src/AElf.Client/AElf.Client.csproj +++ b/src/AElf.Client/AElf.Client.csproj @@ -7,8 +7,6 @@ This is a C# client library, used to communicate with the AElf API. AElf true - 1.3.2 - 9.0 @@ -16,8 +14,8 @@ - - + + From e5bfb8947a0ab6b66486715d369edfb60d4aef01 Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Sat, 15 Jul 2023 09:30:10 +0800 Subject: [PATCH 59/70] refactor(AElfClient): fixed indentation --- src/AElf.Client/AElfClient.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/AElf.Client/AElfClient.cs b/src/AElf.Client/AElfClient.cs index 90bbee0..8faaff9 100644 --- a/src/AElf.Client/AElfClient.cs +++ b/src/AElf.Client/AElfClient.cs @@ -3,14 +3,13 @@ namespace AElf.Client { - public partial class AElfClient : IDisposable { private readonly IHttpService _httpService; private readonly string _baseUrl; private readonly string _userName; private readonly string _password; - + public AElfClient(string baseUrl, int timeOut = 60, string userName = null, string password = null) { _httpService = new HttpService(timeOut); @@ -18,9 +17,9 @@ public AElfClient(string baseUrl, int timeOut = 60, string userName = null, stri _userName = userName; _password = password; } - + private bool _disposed; - + /// public void Dispose() { @@ -28,7 +27,7 @@ public void Dispose() Dispose(true); _disposed = true; } - + /// /// Disposes the resources associated with the object. /// @@ -36,4 +35,5 @@ public void Dispose() protected virtual void Dispose(bool disposing) { } - }} + } +} \ No newline at end of file From 062070370f9f2af08cbb496500c97e762363103e Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Sat, 15 Jul 2023 09:36:25 +0800 Subject: [PATCH 60/70] fix(HttpSerivce): removed ConfigureAwait(false) --- src/AElf.Client/Services/HttpService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AElf.Client/Services/HttpService.cs b/src/AElf.Client/Services/HttpService.cs index 280e385..6ab8425 100644 --- a/src/AElf.Client/Services/HttpService.cs +++ b/src/AElf.Client/Services/HttpService.cs @@ -47,7 +47,7 @@ public HttpService(int timeoutSeconds) HttpStatusCode expectedStatusCode = HttpStatusCode.OK) { var response = await GetResponseAsync(url, version, expectedStatusCode); - await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + await using var stream = await response.Content.ReadAsStreamAsync(); using var streamReader = new StreamReader(stream); using var reader = new JsonTextReader(streamReader); @@ -75,7 +75,7 @@ public HttpService(int timeoutSeconds) var response = await PostResponseAsync(url, parameters, version, true, expectedStatusCode, authenticationHeaderValue); - await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + await using var stream = await response.Content.ReadAsStreamAsync(); using var streamReader = new StreamReader(stream); using var reader = new JsonTextReader(streamReader); @@ -100,7 +100,7 @@ public HttpService(int timeoutSeconds) { var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); - await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + await using var stream = await response.Content.ReadAsStreamAsync(); using var streamReader = new StreamReader(stream); using var reader = new JsonTextReader(streamReader); From 696fdddaddf3e18da12ce9d84ca7f59696d63a5e Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Sun, 23 Jul 2023 18:52:55 +0800 Subject: [PATCH 61/70] refactor(.netstandard2.1): fixed closing bracket indentation --- src/AElf.Client/AElfClient.Block.cs | 3 ++- src/AElf.Client/AElfClient.Chain.cs | 3 ++- src/AElf.Client/AElfClient.Client.cs | 3 ++- src/AElf.Client/AElfClient.Net.cs | 3 ++- src/AElf.Client/AElfClient.Transaction.cs | 3 ++- src/AElf.Client/AElfClientBuilder.cs | 3 ++- src/AElf.Client/AElfClientConstants.cs | 3 ++- src/AElf.Client/Dto/BlockBodyDto.cs | 3 ++- src/AElf.Client/Dto/BlockDto.cs | 3 ++- src/AElf.Client/Dto/BlockHeaderDto.cs | 3 ++- src/AElf.Client/Dto/CalculateTransactionFeeInput.cs | 3 ++- src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs | 3 ++- src/AElf.Client/Dto/ChainStatusDto.cs | 3 ++- src/AElf.Client/Dto/CreateRawTransactionOutput.cs | 3 ++- src/AElf.Client/Dto/ExecuteRawTransactionDto.cs | 3 ++- src/AElf.Client/Dto/ExecuteTransactionDto.cs | 3 ++- src/AElf.Client/Dto/LogEventDto.cs | 3 ++- src/AElf.Client/Dto/MerklePathDto.cs | 3 ++- src/AElf.Client/Dto/NetworkInfoOutput.cs | 3 ++- src/AElf.Client/Dto/PeerDto.cs | 3 ++- src/AElf.Client/Dto/SendRawTransactionInput.cs | 3 ++- src/AElf.Client/Dto/SendRawTransactionOutput.cs | 3 ++- src/AElf.Client/Dto/SendTransactionInput.cs | 3 ++- src/AElf.Client/Dto/SendTransactionOutput.cs | 3 ++- src/AElf.Client/Dto/SendTransactionsInput.cs | 3 ++- src/AElf.Client/Dto/TaskQueueInfoDto.cs | 3 ++- src/AElf.Client/Dto/TransactionDto.cs | 3 ++- src/AElf.Client/Dto/TransactionPoolStatusOutput.cs | 3 ++- src/AElf.Client/Dto/TransactionResultDto.cs | 3 ++- src/AElf.Client/EndpointType.cs | 3 ++- src/AElf.Client/Exception/AElfClientException.cs | 3 ++- src/AElf.Client/Exception/Error.cs | 3 ++- src/AElf.Client/Extensions/StringExtensions.cs | 3 ++- src/AElf.Client/Extensions/TransactionResultDtoExtension.cs | 3 ++- src/AElf.Client/Services/HttpService.cs | 3 ++- src/AElf.Client/Services/IBlockAppService.cs | 3 ++- src/AElf.Client/Services/IChainAppService.cs | 3 ++- src/AElf.Client/Services/IClientService.cs | 3 ++- src/AElf.Client/Services/INetAppService.cs | 3 ++- src/AElf.Client/Services/ITransactionAppService.cs | 3 ++- src/AElf.Client/TransactionBuilder.cs | 3 ++- 41 files changed, 82 insertions(+), 41 deletions(-) diff --git a/src/AElf.Client/AElfClient.Block.cs b/src/AElf.Client/AElfClient.Block.cs index 23a4141..9c5eefe 100644 --- a/src/AElf.Client/AElfClient.Block.cs +++ b/src/AElf.Client/AElfClient.Block.cs @@ -43,4 +43,5 @@ public async Task GetBlockHeightAsync() $"api/blockChain/blockByHeight?blockHeight={blockHeight}&includeTransactions={includeTransactions}"); return await _httpService.GetResponseAsync(url); } - }} + } +} diff --git a/src/AElf.Client/AElfClient.Chain.cs b/src/AElf.Client/AElfClient.Chain.cs index 08289e7..a346c06 100644 --- a/src/AElf.Client/AElfClient.Chain.cs +++ b/src/AElf.Client/AElfClient.Chain.cs @@ -69,4 +69,5 @@ public async Task GetChainIdAsync() var chainId = ChainHelper.ConvertBase58ToChainId(base58ChainId); return chainId; } - }} + } +} diff --git a/src/AElf.Client/AElfClient.Client.cs b/src/AElf.Client/AElfClient.Client.cs index 4fdf3e8..fa42262 100644 --- a/src/AElf.Client/AElfClient.Client.cs +++ b/src/AElf.Client/AElfClient.Client.cs @@ -270,4 +270,5 @@ private void AssertValidTransactionId(params string[] transactionIds) } #endregion - }} + } +} diff --git a/src/AElf.Client/AElfClient.Net.cs b/src/AElf.Client/AElfClient.Net.cs index 05b1dea..723e019 100644 --- a/src/AElf.Client/AElfClient.Net.cs +++ b/src/AElf.Client/AElfClient.Net.cs @@ -81,4 +81,5 @@ private AuthenticationHeaderValue GetAuthenticationHeaderValue() var byteArray = Encoding.ASCII.GetBytes($"{_userName}:{_password}"); return new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); } - }} + } +} diff --git a/src/AElf.Client/AElfClient.Transaction.cs b/src/AElf.Client/AElfClient.Transaction.cs index e41d17b..d05a497 100644 --- a/src/AElf.Client/AElfClient.Transaction.cs +++ b/src/AElf.Client/AElfClient.Transaction.cs @@ -175,4 +175,5 @@ public async Task ExecuteTransactionAsync(ExecuteTransactionDto input) }; return await _httpService.PostResponseAsync(url,parameters); } - }} + } +} diff --git a/src/AElf.Client/AElfClientBuilder.cs b/src/AElf.Client/AElfClientBuilder.cs index 409522a..1d3d6eb 100644 --- a/src/AElf.Client/AElfClientBuilder.cs +++ b/src/AElf.Client/AElfClientBuilder.cs @@ -63,4 +63,5 @@ public AElfClient Build() { return new AElfClient(NodeEndpoint, Timeout, UserName, Password); } - }} + } +} diff --git a/src/AElf.Client/AElfClientConstants.cs b/src/AElf.Client/AElfClientConstants.cs index 4b99680..d611cd3 100644 --- a/src/AElf.Client/AElfClientConstants.cs +++ b/src/AElf.Client/AElfClientConstants.cs @@ -11,4 +11,5 @@ public class AElfClientConstants public const string TestNetSidechain = "https://tdvv-test-node.aelf.io"; public const int MainChainId = 9992731; public const int SidechainId = 9992731; - }} + } +} diff --git a/src/AElf.Client/Dto/BlockBodyDto.cs b/src/AElf.Client/Dto/BlockBodyDto.cs index 0a880b4..059d50e 100644 --- a/src/AElf.Client/Dto/BlockBodyDto.cs +++ b/src/AElf.Client/Dto/BlockBodyDto.cs @@ -8,4 +8,5 @@ public class BlockBodyDto public int TransactionsCount { get; set; } public List Transactions { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/BlockDto.cs b/src/AElf.Client/Dto/BlockDto.cs index 0ae41ea..8ae6f6b 100644 --- a/src/AElf.Client/Dto/BlockDto.cs +++ b/src/AElf.Client/Dto/BlockDto.cs @@ -8,4 +8,5 @@ public class BlockDto public BlockHeaderDto Header { get; set; } public BlockBodyDto Body { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/BlockHeaderDto.cs b/src/AElf.Client/Dto/BlockHeaderDto.cs index 2740608..7651228 100644 --- a/src/AElf.Client/Dto/BlockHeaderDto.cs +++ b/src/AElf.Client/Dto/BlockHeaderDto.cs @@ -24,4 +24,5 @@ public class BlockHeaderDto public string Bloom { get; set; } public string SignerPubkey { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs b/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs index 283c1ae..03f26a9 100644 --- a/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs +++ b/src/AElf.Client/Dto/CalculateTransactionFeeInput.cs @@ -4,4 +4,5 @@ namespace AElf.Client.Dto public class CalculateTransactionFeeInput { public string RawTransaction { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs b/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs index 26e80cc..3f220b5 100644 --- a/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs +++ b/src/AElf.Client/Dto/CalculateTransactionFeeOutput.cs @@ -11,4 +11,5 @@ public class CalculateTransactionFeeOutput public Dictionary TransactionFee { get; set; } public Dictionary ResourceFee { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/ChainStatusDto.cs b/src/AElf.Client/Dto/ChainStatusDto.cs index 5b02c00..a52a8f1 100644 --- a/src/AElf.Client/Dto/ChainStatusDto.cs +++ b/src/AElf.Client/Dto/ChainStatusDto.cs @@ -26,4 +26,5 @@ public class ChainStatusDto public string BestChainHash { get; set; } public long BestChainHeight { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/CreateRawTransactionOutput.cs b/src/AElf.Client/Dto/CreateRawTransactionOutput.cs index ead5fb7..babe46c 100644 --- a/src/AElf.Client/Dto/CreateRawTransactionOutput.cs +++ b/src/AElf.Client/Dto/CreateRawTransactionOutput.cs @@ -4,4 +4,5 @@ namespace AElf.Client.Dto public class CreateRawTransactionOutput { public string RawTransaction { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs b/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs index 23c70fc..e229467 100644 --- a/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs +++ b/src/AElf.Client/Dto/ExecuteRawTransactionDto.cs @@ -12,4 +12,5 @@ public class ExecuteRawTransactionDto /// signature /// public string Signature { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/ExecuteTransactionDto.cs b/src/AElf.Client/Dto/ExecuteTransactionDto.cs index dc8b784..d850791 100644 --- a/src/AElf.Client/Dto/ExecuteTransactionDto.cs +++ b/src/AElf.Client/Dto/ExecuteTransactionDto.cs @@ -7,4 +7,5 @@ public class ExecuteTransactionDto /// raw transaction /// public string RawTransaction { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/LogEventDto.cs b/src/AElf.Client/Dto/LogEventDto.cs index f7a2560..6a7639e 100644 --- a/src/AElf.Client/Dto/LogEventDto.cs +++ b/src/AElf.Client/Dto/LogEventDto.cs @@ -10,4 +10,5 @@ public class LogEventDto public string[] Indexed { get; set; } public string NonIndexed { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/MerklePathDto.cs b/src/AElf.Client/Dto/MerklePathDto.cs index 6bfe0b3..e20e50d 100644 --- a/src/AElf.Client/Dto/MerklePathDto.cs +++ b/src/AElf.Client/Dto/MerklePathDto.cs @@ -12,4 +12,5 @@ public class MerklePathNodeDto { public string Hash { get; set; } public bool IsLeftChildNode { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/NetworkInfoOutput.cs b/src/AElf.Client/Dto/NetworkInfoOutput.cs index 5d95ecb..aa24de1 100644 --- a/src/AElf.Client/Dto/NetworkInfoOutput.cs +++ b/src/AElf.Client/Dto/NetworkInfoOutput.cs @@ -17,4 +17,5 @@ public class NetworkInfoOutput /// total number of open connections between this node and other nodes ///
public int Connections { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/PeerDto.cs b/src/AElf.Client/Dto/PeerDto.cs index 16a3764..39fd297 100644 --- a/src/AElf.Client/Dto/PeerDto.cs +++ b/src/AElf.Client/Dto/PeerDto.cs @@ -23,4 +23,5 @@ public class RequestMetric public string MethodName { get; set; } public string Info { get; set; } public string RequestTime { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/SendRawTransactionInput.cs b/src/AElf.Client/Dto/SendRawTransactionInput.cs index 747c8cc..382ae3e 100644 --- a/src/AElf.Client/Dto/SendRawTransactionInput.cs +++ b/src/AElf.Client/Dto/SendRawTransactionInput.cs @@ -17,4 +17,5 @@ public class SendRawTransactionInput /// return transaction detail or not /// public bool ReturnTransaction { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/SendRawTransactionOutput.cs b/src/AElf.Client/Dto/SendRawTransactionOutput.cs index 947fa1d..0b9487d 100644 --- a/src/AElf.Client/Dto/SendRawTransactionOutput.cs +++ b/src/AElf.Client/Dto/SendRawTransactionOutput.cs @@ -6,4 +6,5 @@ public class SendRawTransactionOutput public string TransactionId { get; set; } public TransactionDto Transaction { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/SendTransactionInput.cs b/src/AElf.Client/Dto/SendTransactionInput.cs index 0f2e8a4..f33625c 100644 --- a/src/AElf.Client/Dto/SendTransactionInput.cs +++ b/src/AElf.Client/Dto/SendTransactionInput.cs @@ -7,4 +7,5 @@ public class SendTransactionInput /// raw transaction /// public string RawTransaction { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/SendTransactionOutput.cs b/src/AElf.Client/Dto/SendTransactionOutput.cs index 4a9e688..9af68a4 100644 --- a/src/AElf.Client/Dto/SendTransactionOutput.cs +++ b/src/AElf.Client/Dto/SendTransactionOutput.cs @@ -4,4 +4,5 @@ namespace AElf.Client.Dto public class SendTransactionOutput { public string TransactionId { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/SendTransactionsInput.cs b/src/AElf.Client/Dto/SendTransactionsInput.cs index 629ae73..33ae65d 100644 --- a/src/AElf.Client/Dto/SendTransactionsInput.cs +++ b/src/AElf.Client/Dto/SendTransactionsInput.cs @@ -7,4 +7,5 @@ public class SendTransactionsInput /// raw transactions /// public string RawTransactions { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/TaskQueueInfoDto.cs b/src/AElf.Client/Dto/TaskQueueInfoDto.cs index 15b1f79..005cf03 100644 --- a/src/AElf.Client/Dto/TaskQueueInfoDto.cs +++ b/src/AElf.Client/Dto/TaskQueueInfoDto.cs @@ -6,4 +6,5 @@ public class TaskQueueInfoDto public string Name { get; set; } public int Size { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/TransactionDto.cs b/src/AElf.Client/Dto/TransactionDto.cs index 1f5147e..b089297 100644 --- a/src/AElf.Client/Dto/TransactionDto.cs +++ b/src/AElf.Client/Dto/TransactionDto.cs @@ -16,4 +16,5 @@ public class TransactionDto public string Params { get; set; } public string Signature { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs b/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs index c214654..e72f545 100644 --- a/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs +++ b/src/AElf.Client/Dto/TransactionPoolStatusOutput.cs @@ -5,4 +5,5 @@ public class TransactionPoolStatusOutput { public int Queued { get; set; } public int Validated { get; set; } - }} + } +} diff --git a/src/AElf.Client/Dto/TransactionResultDto.cs b/src/AElf.Client/Dto/TransactionResultDto.cs index 355e5e8..98caf9c 100644 --- a/src/AElf.Client/Dto/TransactionResultDto.cs +++ b/src/AElf.Client/Dto/TransactionResultDto.cs @@ -20,4 +20,5 @@ public class TransactionResultDto public string ReturnValue { get; set; } public string Error { get; set; } - }} + } +} diff --git a/src/AElf.Client/EndpointType.cs b/src/AElf.Client/EndpointType.cs index 67d0148..feec5d6 100644 --- a/src/AElf.Client/EndpointType.cs +++ b/src/AElf.Client/EndpointType.cs @@ -8,4 +8,5 @@ public enum EndpointType TestNetMainChain, TestNetSidechain, Local - }} + } +} diff --git a/src/AElf.Client/Exception/AElfClientException.cs b/src/AElf.Client/Exception/AElfClientException.cs index 13475d7..b588757 100644 --- a/src/AElf.Client/Exception/AElfClientException.cs +++ b/src/AElf.Client/Exception/AElfClientException.cs @@ -9,4 +9,5 @@ public AElfClientException(string message) : base(message) { } - }} + } +} diff --git a/src/AElf.Client/Exception/Error.cs b/src/AElf.Client/Exception/Error.cs index 33cae9e..2a5af03 100644 --- a/src/AElf.Client/Exception/Error.cs +++ b/src/AElf.Client/Exception/Error.cs @@ -35,4 +35,5 @@ public class Error {InvalidParams, "Invalid params"}, {InvalidSignature, "Invalid signature"} }; - }} + } +} diff --git a/src/AElf.Client/Extensions/StringExtensions.cs b/src/AElf.Client/Extensions/StringExtensions.cs index 891aaa8..efbd584 100644 --- a/src/AElf.Client/Extensions/StringExtensions.cs +++ b/src/AElf.Client/Extensions/StringExtensions.cs @@ -14,4 +14,5 @@ public static Address ToAddress(this string? address) return Address.FromBase58(address); } - }} + } +} diff --git a/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs b/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs index 8701bee..54a830c 100644 --- a/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs +++ b/src/AElf.Client/Extensions/TransactionResultDtoExtension.cs @@ -37,4 +37,5 @@ public static Dictionary GetTransactionFees(this TransactionResult return result; } - }} + } +} diff --git a/src/AElf.Client/Services/HttpService.cs b/src/AElf.Client/Services/HttpService.cs index 6ab8425..a9dcd83 100644 --- a/src/AElf.Client/Services/HttpService.cs +++ b/src/AElf.Client/Services/HttpService.cs @@ -234,4 +234,5 @@ private HttpClient GetHttpClient(string? version = null) } #endregion - }} + } +} diff --git a/src/AElf.Client/Services/IBlockAppService.cs b/src/AElf.Client/Services/IBlockAppService.cs index 1d5f9ae..4697d65 100644 --- a/src/AElf.Client/Services/IBlockAppService.cs +++ b/src/AElf.Client/Services/IBlockAppService.cs @@ -11,4 +11,5 @@ public interface IBlockAppService Task GetBlockByHashAsync(string blockHash, bool includeTransactions = false); Task GetBlockByHeightAsync(long blockHeight, bool includeTransactions = false); - }} + } +} diff --git a/src/AElf.Client/Services/IChainAppService.cs b/src/AElf.Client/Services/IChainAppService.cs index e149c32..08a06f3 100644 --- a/src/AElf.Client/Services/IChainAppService.cs +++ b/src/AElf.Client/Services/IChainAppService.cs @@ -15,4 +15,5 @@ public interface IChainAppService Task> GetTaskQueueStatusAsync(); Task GetChainIdAsync(); - }} + } +} diff --git a/src/AElf.Client/Services/IClientService.cs b/src/AElf.Client/Services/IClientService.cs index f97c7ab..c605419 100644 --- a/src/AElf.Client/Services/IClientService.cs +++ b/src/AElf.Client/Services/IClientService.cs @@ -13,4 +13,5 @@ public interface IClientService Task
GetContractAddressByNameAsync(Hash contractNameHash); string GetAddressFromPubKey(string pubKey); KeyPairInfo GenerateKeyPairInfo(); - }} + } +} diff --git a/src/AElf.Client/Services/INetAppService.cs b/src/AElf.Client/Services/INetAppService.cs index c120aeb..daff3f5 100644 --- a/src/AElf.Client/Services/INetAppService.cs +++ b/src/AElf.Client/Services/INetAppService.cs @@ -14,4 +14,5 @@ public interface INetAppService Task?> GetPeersAsync(bool withMetrics); Task GetNetworkInfoAsync(); - }} + } +} diff --git a/src/AElf.Client/Services/ITransactionAppService.cs b/src/AElf.Client/Services/ITransactionAppService.cs index e70a846..2c98388 100644 --- a/src/AElf.Client/Services/ITransactionAppService.cs +++ b/src/AElf.Client/Services/ITransactionAppService.cs @@ -29,4 +29,5 @@ public interface ITransactionAppService Task GetMerklePathByTransactionIdAsync(string transactionId); Task CalculateTransactionFeeAsync(CalculateTransactionFeeInput input); - }} + } +} diff --git a/src/AElf.Client/TransactionBuilder.cs b/src/AElf.Client/TransactionBuilder.cs index 4db766e..00d088e 100644 --- a/src/AElf.Client/TransactionBuilder.cs +++ b/src/AElf.Client/TransactionBuilder.cs @@ -59,4 +59,5 @@ public Transaction Build() var signedTx = _aelfClient.SignTransaction(PrivateKey, unsignedTx); return signedTx; } - }} + } +} From e31c098d983a85d4a88098602c76437abbe84b3c Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Sun, 23 Jul 2023 22:34:58 +0800 Subject: [PATCH 62/70] refactor(HttpService): refactored duplicate code --- src/AElf.Client/Services/HttpService.cs | 32 ++++++++++++------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/AElf.Client/Services/HttpService.cs b/src/AElf.Client/Services/HttpService.cs index a9dcd83..8e9b5f0 100644 --- a/src/AElf.Client/Services/HttpService.cs +++ b/src/AElf.Client/Services/HttpService.cs @@ -34,6 +34,16 @@ public HttpService(int timeoutSeconds) { TimeoutSeconds = timeoutSeconds; } + + private static T GetResponse(Stream stream) + { + using var streamReader = new StreamReader(stream); + using var reader = new JsonTextReader(streamReader); + + var serializer = new JsonSerializer(); + var ret = serializer.Deserialize(reader); + return ret; + } /// /// Get request. @@ -48,15 +58,11 @@ public HttpService(int timeoutSeconds) { var response = await GetResponseAsync(url, version, expectedStatusCode); await using var stream = await response.Content.ReadAsStreamAsync(); - using var streamReader = new StreamReader(stream); - using var reader = new JsonTextReader(streamReader); - - var serializer = new JsonSerializer(); - var ret = serializer.Deserialize(reader); - + var ret = GetResponse(stream); + return ret; } - + /// /// Post request. /// @@ -76,11 +82,7 @@ public HttpService(int timeoutSeconds) authenticationHeaderValue); await using var stream = await response.Content.ReadAsStreamAsync(); - using var streamReader = new StreamReader(stream); - using var reader = new JsonTextReader(streamReader); - - var serializer = new JsonSerializer(); - var ret = serializer.Deserialize(reader); + var ret = GetResponse(stream); return ret; } @@ -101,11 +103,7 @@ public HttpService(int timeoutSeconds) var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); await using var stream = await response.Content.ReadAsStreamAsync(); - using var streamReader = new StreamReader(stream); - using var reader = new JsonTextReader(streamReader); - - var serializer = new JsonSerializer(); - var ret = serializer.Deserialize(reader); + var ret = GetResponse(stream); return ret; } From 6a236424bcd4da2943e1f7f748d8e8535823d5f6 Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Mon, 28 Aug 2023 17:44:09 +0800 Subject: [PATCH 63/70] fix(netstand2.1): changed syntax for compatibility with C# 8.0 --- .../AElf.Client.Protobuf.csproj | 2 +- src/AElf.Client/AElf.Client.csproj | 4 +- src/AElf.Client/Helper/EndpointHelper.cs | 57 +++++++++---------- src/AElf.Client/Services/HttpService.cs | 12 ++-- 4 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj index f3ec379..59576ca 100644 --- a/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj +++ b/src/AElf.Client.Protobuf/AElf.Client.Protobuf.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj index c9bef7c..52a6212 100644 --- a/src/AElf.Client/AElf.Client.csproj +++ b/src/AElf.Client/AElf.Client.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/src/AElf.Client/Helper/EndpointHelper.cs b/src/AElf.Client/Helper/EndpointHelper.cs index 3d04103..da410e4 100644 --- a/src/AElf.Client/Helper/EndpointHelper.cs +++ b/src/AElf.Client/Helper/EndpointHelper.cs @@ -21,45 +21,40 @@ public static bool TryParse(string endpointString, out DnsEndPoint? endpoint, string host; var port = -1; - switch (values.Length) + if(values.Length <= 2) { - case <= 2: - { - // ipv4 or hostname - host = values[0]; - - if (values.Length == 1) - { - port = defaultPort; - } - else - { - var parsedPort = GetPort(values[1]); - - if (parsedPort == 0) - return false; - - port = parsedPort; - } + // ipv4 or hostname + host = values[0]; - break; + if (values.Length == 1) + { + port = defaultPort; } - //ipv6 - //could be [a:b:c]:d - case > 2 when values[0].StartsWith("[") && values[values.Length - 2].EndsWith("]"): + else { - host = string.Join(":", values.Take(values.Length - 1).ToArray()); - var parsedPort = GetPort(values[values.Length - 1]); + var parsedPort = GetPort(values[1]); if (parsedPort == 0) return false; - break; + + port = parsedPort; } - // [a:b:c] or a:b:c - case > 2: - host = endpointString; - port = defaultPort; - break; + } + //ipv6 + //could be [a:b:c]:d + else if(values.Length > 2 && (values[0].StartsWith("[") && values[^2].EndsWith("]"))) + { + host = string.Join(":", values.Take(values.Length - 1).ToArray()); + var parsedPort = GetPort(values[^1]); + + if (parsedPort == 0) + return false; + } + // [a:b:c] or a:b:c + else + { + host = endpointString; + port = defaultPort; } if (port == -1) diff --git a/src/AElf.Client/Services/HttpService.cs b/src/AElf.Client/Services/HttpService.cs index 8e9b5f0..ae69046 100644 --- a/src/AElf.Client/Services/HttpService.cs +++ b/src/AElf.Client/Services/HttpService.cs @@ -13,14 +13,14 @@ namespace AElf.Client.Service public interface IHttpService { - Task GetResponseAsync(string url, string? version = null, + Task GetResponseAsync(string url, string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK); - Task PostResponseAsync(string url, Dictionary parameters, + Task PostResponseAsync(string url, Dictionary parameters, string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, AuthenticationHeaderValue? authenticationHeaderValue = null); - Task DeleteResponseAsObjectAsync(string url, string? version = null, + Task DeleteResponseAsObjectAsync(string url, string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, AuthenticationHeaderValue authenticationHeaderValue = null); } @@ -53,7 +53,7 @@ private static T GetResponse(Stream stream) /// /// /// - public async Task GetResponseAsync(string url, string? version = null, + public async Task GetResponseAsync(string url, string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) { var response = await GetResponseAsync(url, version, expectedStatusCode); @@ -73,7 +73,7 @@ private static T GetResponse(Stream stream) /// /// /// - public async Task PostResponseAsync(string url, Dictionary parameters, + public async Task PostResponseAsync(string url, Dictionary parameters, string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, AuthenticationHeaderValue? authenticationHeaderValue = null) @@ -96,7 +96,7 @@ private static T GetResponse(Stream stream) /// /// /// - public async Task DeleteResponseAsObjectAsync(string url, string? version = null, + public async Task DeleteResponseAsObjectAsync(string url, string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, AuthenticationHeaderValue authenticationHeaderValue = null) { From 3778f3e92cc294858569ec3ca81443c72ebd3c86 Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Tue, 29 Aug 2023 11:15:32 +0800 Subject: [PATCH 64/70] fix(netstand2.1): added missing dependency for ABP csproj --- src/AElf.Client.Abp/AElf.Client.Abp.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AElf.Client.Abp/AElf.Client.Abp.csproj b/src/AElf.Client.Abp/AElf.Client.Abp.csproj index 2f6815f..3cd7cf1 100644 --- a/src/AElf.Client.Abp/AElf.Client.Abp.csproj +++ b/src/AElf.Client.Abp/AElf.Client.Abp.csproj @@ -12,6 +12,7 @@ + From 64c8b9c524320e4c6c6e2da788aac583d2e94ae4 Mon Sep 17 00:00:00 2001 From: zhifenglee-aelf Date: Fri, 29 Sep 2023 10:17:26 +0800 Subject: [PATCH 65/70] refactor(dependency): changed dependency to AElf.Client --- src/AElf.Client.Abp/AElf.Client.Abp.csproj | 1 - src/AElf.Client/AElf.Client.csproj | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AElf.Client.Abp/AElf.Client.Abp.csproj b/src/AElf.Client.Abp/AElf.Client.Abp.csproj index 3cd7cf1..2f6815f 100644 --- a/src/AElf.Client.Abp/AElf.Client.Abp.csproj +++ b/src/AElf.Client.Abp/AElf.Client.Abp.csproj @@ -12,7 +12,6 @@ - diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj index 52a6212..259e45a 100644 --- a/src/AElf.Client/AElf.Client.csproj +++ b/src/AElf.Client/AElf.Client.csproj @@ -17,6 +17,7 @@ + From 4901e528aeed0ac01326fd922f8ebe5e0f5b2b07 Mon Sep 17 00:00:00 2001 From: aelf-lu Date: Thu, 21 Dec 2023 09:36:45 +0800 Subject: [PATCH 66/70] feature: add load keystore func --- all.sln | 14 ++++ src/AElf.KeyStore/AElf.KeyStore.csproj | 15 +++++ src/AElf.KeyStore/AElfKeyStoreService.cs | 24 +++++++ .../AElf.KeyStore.Tests.csproj | 34 ++++++++++ .../AElfKeyStoreServiceTests.cs | 65 +++++++++++++++++++ test/AElf.KeyStore.Tests/data/test.json | 21 ++++++ 6 files changed, 173 insertions(+) create mode 100644 src/AElf.KeyStore/AElf.KeyStore.csproj create mode 100644 src/AElf.KeyStore/AElfKeyStoreService.cs create mode 100644 test/AElf.KeyStore.Tests/AElf.KeyStore.Tests.csproj create mode 100644 test/AElf.KeyStore.Tests/AElfKeyStoreServiceTests.cs create mode 100644 test/AElf.KeyStore.Tests/data/test.json diff --git a/all.sln b/all.sln index 3e3a5d1..fdc8295 100644 --- a/all.sln +++ b/all.sln @@ -20,6 +20,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Client.Test", "test\AE EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Client.Abp", "src\AElf.Client.Abp\AElf.Client.Abp.csproj", "{BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.KeyStore", "src\AElf.KeyStore\AElf.KeyStore.csproj", "{74BABFFA-D040-4977-A45E-54385412C706}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.KeyStore.Tests", "test\AElf.KeyStore.Tests\AElf.KeyStore.Tests.csproj", "{1085F2A7-95F9-4941-AA7C-3CD1A5DAE016}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +37,8 @@ Global {BE0E29FA-A9C6-4E03-9E0C-297CCF7C5729} = {5D1BDC45-D6F1-4359-868B-CB85CEC4ABD8} {4D019C99-8B1C-42B0-8630-F1E3661F414B} = {7CD2B508-C765-4720-B430-94E79135797A} {BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F} = {940361AC-2167-4D30-A4F6-9A543C608196} + {74BABFFA-D040-4977-A45E-54385412C706} = {940361AC-2167-4D30-A4F6-9A543C608196} + {1085F2A7-95F9-4941-AA7C-3CD1A5DAE016} = {7CD2B508-C765-4720-B430-94E79135797A} EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1AE7844D-B4D9-4F5A-9D25-7E551B61138E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -63,5 +69,13 @@ Global {BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F}.Debug|Any CPU.Build.0 = Debug|Any CPU {BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F}.Release|Any CPU.ActiveCfg = Release|Any CPU {BBE11EF4-5CD6-4918-8E6C-74BF61C1A87F}.Release|Any CPU.Build.0 = Release|Any CPU + {74BABFFA-D040-4977-A45E-54385412C706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74BABFFA-D040-4977-A45E-54385412C706}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74BABFFA-D040-4977-A45E-54385412C706}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74BABFFA-D040-4977-A45E-54385412C706}.Release|Any CPU.Build.0 = Release|Any CPU + {1085F2A7-95F9-4941-AA7C-3CD1A5DAE016}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1085F2A7-95F9-4941-AA7C-3CD1A5DAE016}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1085F2A7-95F9-4941-AA7C-3CD1A5DAE016}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1085F2A7-95F9-4941-AA7C-3CD1A5DAE016}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/src/AElf.KeyStore/AElf.KeyStore.csproj b/src/AElf.KeyStore/AElf.KeyStore.csproj new file mode 100644 index 0000000..c7dc814 --- /dev/null +++ b/src/AElf.KeyStore/AElf.KeyStore.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + enable + enable + AElf.KeyStore + + + + + + + + \ No newline at end of file diff --git a/src/AElf.KeyStore/AElfKeyStoreService.cs b/src/AElf.KeyStore/AElfKeyStoreService.cs new file mode 100644 index 0000000..f1021b8 --- /dev/null +++ b/src/AElf.KeyStore/AElfKeyStoreService.cs @@ -0,0 +1,24 @@ +using AElf.Cryptography; +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/AElf.KeyStore.Tests.csproj b/test/AElf.KeyStore.Tests/AElf.KeyStore.Tests.csproj new file mode 100644 index 0000000..4f919bc --- /dev/null +++ b/test/AElf.KeyStore.Tests/AElf.KeyStore.Tests.csproj @@ -0,0 +1,34 @@ + + + + net6.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/AElf.KeyStore.Tests/AElfKeyStoreServiceTests.cs b/test/AElf.KeyStore.Tests/AElfKeyStoreServiceTests.cs new file mode 100644 index 0000000..6ea761b --- /dev/null +++ b/test/AElf.KeyStore.Tests/AElfKeyStoreServiceTests.cs @@ -0,0 +1,65 @@ +// ReSharper disable StringLiteralTypo + +using Xunit; + +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/test.json"); + Assert.Equal(ByteArrayHelper.HexStringToByteArray(PrivateKeyHex), privateKey); + } + +} \ No newline at end of file diff --git a/test/AElf.KeyStore.Tests/data/test.json b/test/AElf.KeyStore.Tests/data/test.json new file mode 100644 index 0000000..14dcccc --- /dev/null +++ b/test/AElf.KeyStore.Tests/data/test.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 From 95646f25d04e715ff39704b68656313ccfe76501 Mon Sep 17 00:00:00 2001 From: aelf-lu Date: Thu, 18 Jan 2024 15:09:39 +0800 Subject: [PATCH 67/70] fix: using net6.0 syntax --- .../AElf.KeyStore.Tests.csproj | 1 - .../AElfKeyStoreServiceTests.cs | 38 +++++++++---------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/test/AElf.KeyStore.Tests/AElf.KeyStore.Tests.csproj b/test/AElf.KeyStore.Tests/AElf.KeyStore.Tests.csproj index 4f919bc..d823e62 100644 --- a/test/AElf.KeyStore.Tests/AElf.KeyStore.Tests.csproj +++ b/test/AElf.KeyStore.Tests/AElf.KeyStore.Tests.csproj @@ -4,7 +4,6 @@ net6.0 enable enable - 11 false diff --git a/test/AElf.KeyStore.Tests/AElfKeyStoreServiceTests.cs b/test/AElf.KeyStore.Tests/AElfKeyStoreServiceTests.cs index 6ea761b..9377014 100644 --- a/test/AElf.KeyStore.Tests/AElfKeyStoreServiceTests.cs +++ b/test/AElf.KeyStore.Tests/AElfKeyStoreServiceTests.cs @@ -25,30 +25,30 @@ public void EncryptKeyStoreAsJson_Test() [Fact] public void DecryptKeyStoreFromJson_Test() { - const string jsonKeyStore = - """ + const string jsonKeyStore = + @" { - "crypto": { - "cipher": "aes-128-ctr", - "ciphertext": "1734a897caeea53e306fa6908fca443e598ea1cb6361fb27e5c45de61a26eb25", - "cipherparams": { - "iv": "36f00104f0488386db1f3e3d37b14bfe" + ""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" + ""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 + ""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); From 9b35600e3dfb2536b2063fd560eae7ab2bc6675c Mon Sep 17 00:00:00 2001 From: aelf-lu Date: Thu, 28 Mar 2024 17:53:50 +0800 Subject: [PATCH 68/70] fix: fix dependency version --- src/AElf.KeyStore/AElf.KeyStore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AElf.KeyStore/AElf.KeyStore.csproj b/src/AElf.KeyStore/AElf.KeyStore.csproj index c7dc814..9b0d2ca 100644 --- a/src/AElf.KeyStore/AElf.KeyStore.csproj +++ b/src/AElf.KeyStore/AElf.KeyStore.csproj @@ -9,7 +9,7 @@ - + \ No newline at end of file From 375ae712cffd5787ce204c91d88c36fd396326e5 Mon Sep 17 00:00:00 2001 From: aelf-lu Date: Wed, 3 Apr 2024 11:42:10 +0800 Subject: [PATCH 69/70] fix: fix dependency version --- src/AElf.KeyStore/AElf.KeyStore.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AElf.KeyStore/AElf.KeyStore.csproj b/src/AElf.KeyStore/AElf.KeyStore.csproj index 9b0d2ca..c54a547 100644 --- a/src/AElf.KeyStore/AElf.KeyStore.csproj +++ b/src/AElf.KeyStore/AElf.KeyStore.csproj @@ -8,8 +8,8 @@ - - + + \ No newline at end of file From 1beaf280d8ebe2cf40537f2ffb04fb636755a6fd Mon Sep 17 00:00:00 2001 From: aelf-lu Date: Thu, 4 Apr 2024 18:02:44 +0800 Subject: [PATCH 70/70] fix: fix Nethereum.KeyStore version --- src/AElf.Client/AElf.Client.csproj | 2 +- src/AElf.KeyStore/AElf.KeyStore.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AElf.Client/AElf.Client.csproj b/src/AElf.Client/AElf.Client.csproj index 259e45a..9d9eca7 100644 --- a/src/AElf.Client/AElf.Client.csproj +++ b/src/AElf.Client/AElf.Client.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/AElf.KeyStore/AElf.KeyStore.csproj b/src/AElf.KeyStore/AElf.KeyStore.csproj index c54a547..c7dc814 100644 --- a/src/AElf.KeyStore/AElf.KeyStore.csproj +++ b/src/AElf.KeyStore/AElf.KeyStore.csproj @@ -8,7 +8,7 @@ - +