diff --git a/.devcontainer/devcontainer.dockerfile b/.devcontainer/devcontainer.dockerfile
new file mode 100644
index 0000000000..23c644a110
--- /dev/null
+++ b/.devcontainer/devcontainer.dockerfile
@@ -0,0 +1,6 @@
+# https://github.com/dotnet/dotnet-docker/blob/main/README.sdk.md
+# https://mcr.microsoft.com/en-us/artifact/mar/dotnet/sdk/tags <-- this shows all images
+FROM mcr.microsoft.com/dotnet/sdk:10.0
+
+# Install the libleveldb-dev package
+RUN apt-get update && apt-get install -y libleveldb-dev
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000000..5e9bdf6374
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,17 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the
+// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
+{
+ "name": "C# (.NET)",
+ "build": {
+ // Path is relative to the devcontainer.json file.
+ "dockerfile": "devcontainer.dockerfile"
+ },
+ "postCreateCommand": "dotnet build",
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "ms-dotnettools.csdevkit"
+ ]
+ }
+ }
+}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000..48584f5d6e
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,263 @@
+###############################
+# Core EditorConfig Options #
+###############################
+
+# dotnet-format requires version 3.1.37601
+# dotnet tool update -g dotnet-format
+# remember to have: git config --global core.autocrlf false #(which is usually default)
+
+# top-most EditorConfig file
+root = true
+
+# Don't use tabs for indentation.
+[*]
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+charset = utf-8
+end_of_line = lf
+
+# (Please don't specify an indent_size here; that has too many unintended consequences.)
+spelling_exclusion_path = SpellingExclusions.dic
+
+# Code files
+[*.{cs,csx,vb,vbx}]
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+charset = utf-8
+
+# XML project files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
+indent_size = 2
+
+# XML config files
+[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
+indent_size = 2
+
+# JSON files
+[*.json]
+indent_size = 2
+
+# Powershell files
+[*.ps1]
+indent_size = 2
+
+# Shell script files
+[*.sh]
+end_of_line = lf
+indent_size = 2
+
+# YAML files
+[*.yml]
+end_of_line = lf
+indent_size = 2
+
+# Dotnet code style settings:
+[*.{cs,vb}]
+# Use file-scoped namespace
+csharp_style_namespace_declarations = file_scoped:warning
+
+# Member can be made 'readonly'
+csharp_style_prefer_readonly_struct_member = true
+dotnet_diagnostic.IDE0251.severity = warning
+
+dotnet_diagnostic.CS1591.severity = silent
+// Use primary constructor
+csharp_style_prefer_primary_constructors = false
+
+# Sort using and Import directives with System.* appearing first
+dotnet_sort_system_directives_first = false
+dotnet_separate_import_directive_groups = false
+
+# Avoid "this." and "Me." if not necessary
+dotnet_style_qualification_for_field = false:warning
+dotnet_style_qualification_for_property = false:warning
+dotnet_style_qualification_for_method = false:warning
+dotnet_style_qualification_for_event = false:warning
+
+# Use language keywords instead of framework type names for type references
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+
+# Suggest more modern language features when available
+dotnet_style_object_initializer = true:warning
+dotnet_style_collection_initializer = true:warning
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_prefer_collection_expression = never
+
+# Whitespace options
+dotnet_style_allow_multiple_blank_lines_experimental = false
+
+# Non-private static fields are PascalCase
+dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields
+dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style
+
+dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field
+dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
+dotnet_naming_symbols.non_private_static_fields.required_modifiers = static
+
+dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case
+
+# Non-private readonly fields are PascalCase
+dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.symbols = non_private_readonly_fields
+dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.style = non_private_readonly_field_style
+
+dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field
+dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
+dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly
+
+dotnet_naming_style.non_private_readonly_field_style.capitalization = pascal_case
+
+# Local functions are PascalCase
+dotnet_naming_rule.local_functions_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions
+dotnet_naming_rule.local_functions_should_be_pascal_case.style = local_function_style
+
+dotnet_naming_symbols.local_functions.applicable_kinds = local_function
+
+dotnet_naming_style.local_function_style.capitalization = pascal_case
+
+file_header_template = Copyright (C) 2015-2025 The Neo Project.\n\n{fileName} file belongs to the neo project and is free\nsoftware distributed under the MIT software license, see the\naccompanying file LICENSE in the main directory of the\nrepository or http://www.opensource.org/licenses/mit-license.php\nfor more details.\n\nRedistribution and use in source and binary forms with or without\nmodifications are permitted.
+
+# Require file header
+dotnet_diagnostic.IDE0073.severity = warning
+
+# RS0016: Only enable if API files are present
+dotnet_public_api_analyzer.require_api_files = true
+
+# IDE0055: Fix formatting
+# Workaround for https://github.com/dotnet/roslyn/issues/70570
+dotnet_diagnostic.IDE0055.severity = warning
+
+# CSharp code style settings:
+[*.cs]
+# Newline settings
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = flush_left
+
+# Whitespace options
+csharp_style_allow_embedded_statements_on_same_line_experimental = false
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
+csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false
+csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false
+
+# Prefer method-like constructs to have a block body
+csharp_style_expression_bodied_methods = false:none
+csharp_style_expression_bodied_constructors = false:none
+csharp_style_expression_bodied_operators = false:none
+
+# Prefer property-like constructs to have an expression-body
+csharp_style_expression_bodied_properties = true:none
+csharp_style_expression_bodied_indexers = true:none
+csharp_style_expression_bodied_accessors = true:none
+
+# IDE0230: Use UTF-8 string literal
+csharp_style_prefer_utf8_string_literals = true:silent
+
+# Suggest more modern language features when available
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+csharp_style_prefer_extended_property_pattern = true:suggestion
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = do_not_ignore
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Blocks are allowed
+csharp_prefer_braces = true:silent
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = true
+
+# IDE0060: Remove unused parameter
+dotnet_diagnostic.IDE0060.severity = none
+
+[src/{Analyzers,CodeStyle,Features,Workspaces,EditorFeatures,VisualStudio}/**/*.{cs,vb}]
+
+# Avoid "this." and "Me." if not necessary
+dotnet_diagnostic.IDE0003.severity = warning
+dotnet_diagnostic.IDE0009.severity = warning
+
+# IDE0011: Add braces
+csharp_prefer_braces = when_multiline:warning
+# NOTE: We need the below severity entry for Add Braces due to https://github.com/dotnet/roslyn/issues/44201
+dotnet_diagnostic.IDE0011.severity = warning
+
+# IDE0040: Add accessibility modifiers
+dotnet_diagnostic.IDE0040.severity = warning
+
+# IDE0052: Remove unread private member
+dotnet_diagnostic.IDE0052.severity = warning
+
+# IDE0059: Unnecessary assignment to a value
+dotnet_diagnostic.IDE0059.severity = warning
+
+# Use collection expression for array
+dotnet_diagnostic.IDE0300.severity = warning
+
+# CA1012: Abstract types should not have public constructors
+dotnet_diagnostic.CA1012.severity = warning
+
+# CA1822: Make member static
+dotnet_diagnostic.CA1822.severity = warning
+
+# csharp_style_allow_embedded_statements_on_same_line_experimental
+dotnet_diagnostic.IDE2001.severity = warning
+
+# csharp_style_allow_blank_lines_between_consecutive_braces_experimental
+dotnet_diagnostic.IDE2002.severity = warning
+
+# csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental
+dotnet_diagnostic.IDE2004.severity = warning
+
+# csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental
+dotnet_diagnostic.IDE2005.severity = warning
+
+# csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental
+dotnet_diagnostic.IDE2006.severity = warning
+
+[src/{VisualStudio}/**/*.{cs,vb}]
+# CA1822: Make member static
+# There is a risk of accidentally breaking an internal API that partners rely on though IVT.
+dotnet_code_quality.CA1822.api_surface = private
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..3a65aebf75
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,70 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text eol=lf
+*.cs text eol=lf
+*.csproj text eol=lf
+*.props text eol=lf
+*.json text eol=lf
+*.targets text eol=lf
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+*.sln text eol=crlf
+#*.csproj text eol=crlf
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+*.jpg binary
+*.png binary
+*.gif binary
+*.ico binary
+*.zip binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000000..f69eccca73
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,31 @@
+---
+name: Bug report
+about: Create a report to detail an error or unexpected behavior
+title: ''
+labels: ''
+assignees: ''
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Open the project, run '...'
+2. Type '...' or do '...'
+3. ...
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Platform:**
+ - OS: [e.g. Windows 10 x64]
+ - Version [e.g. neo-cli 2.10.2]
+
+**(Optional) Additional context**
+Add any other context about the problem here.
+
+However, if your issue does not fit these aforementioned criteria, or it can be understood in another manner, feel free to open it in a different format.
diff --git a/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md b/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md
new file mode 100644
index 0000000000..ddc181fabb
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-or-enhancement-request.md
@@ -0,0 +1,27 @@
+---
+name: Feature or enhancement request
+about: Suggest an idea for Neo
+title: ''
+labels: Discussion
+assignees: ''
+---
+
+**Summary or problem description**
+A summary of the problem you want to solve or metric you want to improve
+
+**Do you have any solution you want to propose?**
+A clear and concise description of what you expect with this change.
+
+**Where in the software does this update applies to?**
+- Compiler
+- Consensus
+- CLI
+- Plugins
+- Ledger
+- Network Policy
+- P2P (TCP)
+- RPC (HTTP)
+- SDK
+- VM
+- Other:
+
diff --git a/.github/ISSUE_TEMPLATE/questions.md b/.github/ISSUE_TEMPLATE/questions.md
new file mode 100644
index 0000000000..4945492ae3
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/questions.md
@@ -0,0 +1,9 @@
+---
+name: Questions
+about: Questions about Neo Platform
+title: ''
+labels: Question
+assignees: ''
+---
+
+**Delete this: We would like to use GitHub for bug reports and feature requests only however if you are unable to get support from our team in: our [Discord](https://discord.io/neo) server or in our [offical documentation](https://docs.neo.org/docs/en-us/index.html), feel encouraged to create an issue here on GitHub.**
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000000..e093c7c141
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,47 @@
+# Description
+
+
+
+# Change Log
+
+
+Fixes # (issue)
+
+## Type of change
+
+
+
+- [ ] Optimization (the change is only an optimization)
+- [ ] Style (the change is only a code style for better maintenance or standard purpose)
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] This change requires a documentation update
+
+# How Has This Been Tested?
+
+
+
+- [ ] Unit Testing
+- [ ] Run Application
+- [ ] Local Computer Tests
+- [ ] No Testing
+
+
+# Checklist:
+
+- [ ] My code follows the style guidelines of this project
+- [ ] I have performed a self-review of my code
+- [ ] I have commented my code, particularly in hard-to-understand areas
+- [ ] I have made corresponding changes to the documentation
+- [ ] My changes generate no new warnings
+- [ ] I have added tests that prove my fix is effective or that my feature works
+- [ ] New and existing unit tests pass locally with my changes
+- [ ] Any dependent changes have been merged and published in downstream modules
diff --git a/.github/images/compiler.png b/.github/images/compiler.png
new file mode 100644
index 0000000000..affa7ca8ac
Binary files /dev/null and b/.github/images/compiler.png differ
diff --git a/.github/images/consensus.png b/.github/images/consensus.png
new file mode 100644
index 0000000000..b1c6a009c5
Binary files /dev/null and b/.github/images/consensus.png differ
diff --git a/.github/images/cosmetic.png b/.github/images/cosmetic.png
new file mode 100644
index 0000000000..8793610920
Binary files /dev/null and b/.github/images/cosmetic.png differ
diff --git a/.github/images/discord-logo.png b/.github/images/discord-logo.png
new file mode 100644
index 0000000000..f53cf1b2e2
Binary files /dev/null and b/.github/images/discord-logo.png differ
diff --git a/.github/images/discussion.png b/.github/images/discussion.png
new file mode 100644
index 0000000000..c9b09dcfe5
Binary files /dev/null and b/.github/images/discussion.png differ
diff --git a/.github/images/enhancement.png b/.github/images/enhancement.png
new file mode 100644
index 0000000000..34fc8c9775
Binary files /dev/null and b/.github/images/enhancement.png differ
diff --git a/.github/images/house-keeping.png b/.github/images/house-keeping.png
new file mode 100644
index 0000000000..84db938661
Binary files /dev/null and b/.github/images/house-keeping.png differ
diff --git a/.github/images/ledger.png b/.github/images/ledger.png
new file mode 100644
index 0000000000..babf6a3ca7
Binary files /dev/null and b/.github/images/ledger.png differ
diff --git a/.github/images/medium-logo.png b/.github/images/medium-logo.png
new file mode 100644
index 0000000000..8ff3fb659a
Binary files /dev/null and b/.github/images/medium-logo.png differ
diff --git a/.github/images/migration.png b/.github/images/migration.png
new file mode 100644
index 0000000000..69ca781055
Binary files /dev/null and b/.github/images/migration.png differ
diff --git a/.github/images/network-policy.png b/.github/images/network-policy.png
new file mode 100644
index 0000000000..84452a613e
Binary files /dev/null and b/.github/images/network-policy.png differ
diff --git a/.github/images/new-feature.png b/.github/images/new-feature.png
new file mode 100644
index 0000000000..fba5012ff4
Binary files /dev/null and b/.github/images/new-feature.png differ
diff --git a/.github/images/nnt-logo.jpg b/.github/images/nnt-logo.jpg
new file mode 100644
index 0000000000..dfa91f5695
Binary files /dev/null and b/.github/images/nnt-logo.jpg differ
diff --git a/.github/images/p2p.png b/.github/images/p2p.png
new file mode 100644
index 0000000000..d638bd2342
Binary files /dev/null and b/.github/images/p2p.png differ
diff --git a/.github/images/ready-to-implement.png b/.github/images/ready-to-implement.png
new file mode 100644
index 0000000000..b5366b2c85
Binary files /dev/null and b/.github/images/ready-to-implement.png differ
diff --git a/.github/images/reddit-logo.png b/.github/images/reddit-logo.png
new file mode 100644
index 0000000000..be704a89e7
Binary files /dev/null and b/.github/images/reddit-logo.png differ
diff --git a/.github/images/rpc.png b/.github/images/rpc.png
new file mode 100644
index 0000000000..24b6c35375
Binary files /dev/null and b/.github/images/rpc.png differ
diff --git a/.github/images/sdk.png b/.github/images/sdk.png
new file mode 100644
index 0000000000..7e46ae0f74
Binary files /dev/null and b/.github/images/sdk.png differ
diff --git a/.github/images/solution-design.png b/.github/images/solution-design.png
new file mode 100644
index 0000000000..552c083d0b
Binary files /dev/null and b/.github/images/solution-design.png differ
diff --git a/.github/images/telegram-logo.png b/.github/images/telegram-logo.png
new file mode 100644
index 0000000000..7c86be4be6
Binary files /dev/null and b/.github/images/telegram-logo.png differ
diff --git a/.github/images/to-review.png b/.github/images/to-review.png
new file mode 100644
index 0000000000..25054ecc88
Binary files /dev/null and b/.github/images/to-review.png differ
diff --git a/.github/images/twitter-logo.png b/.github/images/twitter-logo.png
new file mode 100644
index 0000000000..cb90d62291
Binary files /dev/null and b/.github/images/twitter-logo.png differ
diff --git a/.github/images/vm.png b/.github/images/vm.png
new file mode 100644
index 0000000000..103970371d
Binary files /dev/null and b/.github/images/vm.png differ
diff --git a/.github/images/wallet.png b/.github/images/wallet.png
new file mode 100644
index 0000000000..42705c14ff
Binary files /dev/null and b/.github/images/wallet.png differ
diff --git a/.github/images/we-chat-logo.png b/.github/images/we-chat-logo.png
new file mode 100644
index 0000000000..201e08c106
Binary files /dev/null and b/.github/images/we-chat-logo.png differ
diff --git a/.github/images/weibo-logo.png b/.github/images/weibo-logo.png
new file mode 100644
index 0000000000..364b4bc823
Binary files /dev/null and b/.github/images/weibo-logo.png differ
diff --git a/.github/images/youtube-logo.png b/.github/images/youtube-logo.png
new file mode 100644
index 0000000000..3c79227977
Binary files /dev/null and b/.github/images/youtube-logo.png differ
diff --git a/.github/workflows/auto-labels.yml b/.github/workflows/auto-labels.yml
new file mode 100644
index 0000000000..80f329540d
--- /dev/null
+++ b/.github/workflows/auto-labels.yml
@@ -0,0 +1,28 @@
+name: Auto-label PRs
+
+on:
+ pull_request_target:
+ types: [opened, synchronize, reopened]
+
+permissions:
+ pull-requests: write
+
+jobs:
+ add-label:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Add N4 label to PRs targeting master
+ if: github.event.pull_request.base.ref == 'master'
+ uses: actions-ecosystem/action-add-labels@v1.1.3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ labels: |
+ N4
+
+ - name: Add N3 label to PRs targeting master-n3
+ if: github.event.pull_request.base.ref == 'master-n3'
+ uses: actions-ecosystem/action-add-labels@v1.1.3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ labels: |
+ N3
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000000..a30e1a4950
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,129 @@
+name: .NET Core Test and Publish
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+
+env:
+ DOTNET_VERSION: 10.0.x
+
+jobs:
+
+ Check-Vulnerable:
+ name: Scan for Vulnerable Dependencies
+ timeout-minutes: 15
+ runs-on: ubuntu-latest
+ continue-on-error: true
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: ${{ env.DOTNET_VERSION }}
+ - name: Restore
+ run: dotnet restore
+ - name: Scan for Vulnerable Dependencies
+ run: dotnet list package --vulnerable --include-transitive
+
+ Test:
+ timeout-minutes: 15
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, windows-latest, macos-latest]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: ${{ env.DOTNET_VERSION }}
+ - name: Cache NuGet packages
+ uses: actions/cache@v4
+ with:
+ path: ~/.nuget/packages
+ key : ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
+ restore-keys: ${{ runner.os }}-nuget-
+ - name: Check Format (*.cs)
+ if: matrix.os == 'ubuntu-latest'
+ run: dotnet format --verify-no-changes --verbosity diagnostic
+ - name: Test (ALL OS)
+ if: matrix.os != 'ubuntu-latest'
+ run: |
+ dotnet test -p:GITHUB_ACTIONS=true
+ - name: Test (ubuntu)
+ if: matrix.os == 'ubuntu-latest'
+ run: |
+ find tests -name *.csproj | xargs -I % dotnet add % package coverlet.msbuild
+ dotnet test /p:GITHUB_ACTIONS=true /p:CollectCoverage=true /p:CoverletOutput='${{ github.workspace }}/TestResults/coverage/' /p:MergeWith='${{ github.workspace }}/TestResults/coverage/coverage.json' /p:CoverletOutputFormat=\"lcov,json\" -m:1
+ - name: Coveralls
+ if: matrix.os == 'ubuntu-latest'
+ uses: coverallsapp/github-action@v2
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ format: lcov
+ file: ${{ github.workspace }}/TestResults/coverage/coverage.info
+
+ PublishMyGet:
+ if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/')
+ needs: [Test]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+ - name: Setup .NET Core
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: ${{ env.DOTNET_VERSION }}
+ - name: Set Version
+ run: git rev-list --count HEAD | xargs printf 'CI%05d' | xargs -I{} echo 'VERSION_SUFFIX={}' >> $GITHUB_ENV
+ - name : Pack (Everything)
+ run: dotnet pack -c Debug -o out --include-source --version-suffix ${{ env.VERSION_SUFFIX }}
+ - name: Publish to myGet
+ run: dotnet nuget push out/*.nupkg -s https://www.myget.org/F/neo/api/v2/package -k ${MYGET_TOKEN} -ss https://www.myget.org/F/neo/symbols/api/v2/package -sk ${MYGET_TOKEN}
+ env:
+ MYGET_TOKEN: ${{ secrets.MYGET_TOKEN }}
+
+ Release:
+ if: github.ref == 'refs/heads/master' && startsWith(github.repository, 'neo-project/')
+ needs: Test
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v5
+ - name: Get version
+ id: get_version
+ run: |
+ sudo apt install xmlstarlet
+ find src -name Directory.Build.props | xargs xmlstarlet sel -N i=http://schemas.microsoft.com/developer/msbuild/2003 -t -v "concat('version=v',//i:Version/text())" | xargs echo >> $GITHUB_OUTPUT
+ - name: Check tag
+ if: steps.get_version.outputs.version != 'v' && startsWith(steps.get_version.outputs.version, 'v')
+ id: check_tag
+ run: curl -s -I ${{ format('https://github.com/%7B0%7D/releases/tag/%7B1%7D', github.repository, steps.get_version.outputs.version) }} | head -n 1 | cut -d$' ' -f2 | xargs printf "statusCode=%s" | xargs echo >> $GITHUB_OUTPUT
+ - name: Create release
+ if: steps.check_tag.outputs.statusCode == '404'
+ id: create_release
+ uses: actions/create-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ steps.get_version.outputs.version }}
+ release_name: ${{ steps.get_version.outputs.version }}
+ prerelease: ${{ contains(steps.get_version.outputs.version, '-') }}
+ - name: Setup .NET Core
+ if: steps.check_tag.outputs.statusCode == '404'
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: ${{ env.DOTNET_VERSION }}
+ - name: Publish to NuGet
+ if: steps.check_tag.outputs.statusCode == '404'
+ run: |
+ dotnet pack -o out -c Release
+ dotnet nuget push out/*.nupkg -s https://api.nuget.org/v3/index.json -k ${NUGET_TOKEN}
+ env:
+ NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }}
diff --git a/.github/workflows/pkgs-delete.yml b/.github/workflows/pkgs-delete.yml
new file mode 100644
index 0000000000..eef291383a
--- /dev/null
+++ b/.github/workflows/pkgs-delete.yml
@@ -0,0 +1,57 @@
+name: Package Cleanup
+
+on:
+ schedule:
+ - cron: '0 0 * * *' # Run every day at 24:00
+
+jobs:
+
+ delete-git-docker-pkgs:
+ name: Delete Old Docker Images
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Delete Neo Package (docker)
+ uses: actions/delete-package-versions@v4
+ continue-on-error: true
+ with:
+ package-name: Neo
+ package-type: docker
+ min-versions-to-keep: 1
+ token: "${{ secrets.GITHUB_TOKEN }}"
+
+ delete-git-nuget-pkgs:
+ name: Delete Old Nuget Packages
+ strategy:
+ matrix:
+ pkgs:
+ - "Neo.Plugins.StatesDumper"
+ - "Neo.Plugins.StateService"
+ - "Neo.Plugins.Storage.LevelDBStore"
+ - "Neo.Plugins.Storage.RocksDBStore"
+ - "Neo.Plugins.StorageDumper"
+ - "Neo.Plugins.TokensTracker"
+ - "Neo.Wallets.SQLite"
+ - "Neo.Consensus.DBFT"
+ - "Neo.ConsoleService"
+ - "Neo.Cryptography.MPT"
+ - "Neo.Extensions"
+ - "Neo.Network.RPC.RpcClient"
+ - "Neo.Plugins.ApplicationLogs"
+ - "Neo.Plugins.OracleService"
+ - "Neo.Plugins.RpcServer"
+ - "Neo.Json"
+ - "Neo.IO"
+ - "Neo"
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Delete ${{ matrix.pkgs }} Package
+ uses: actions/delete-package-versions@v4
+ continue-on-error: true
+ with:
+ package-name: ${{ matrix.pkgs }}
+ package-type: nuget
+ min-versions-to-keep: 3
+ delete-only-pre-release-versions: "true"
+ token: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/.gitignore b/.gitignore
index 88426a8e9b..b8feea9c3d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -153,10 +153,14 @@ PublishScripts/
# NuGet Packages
*.nupkg
+*.snupkg
+
# The packages folder can be ignored because of Package Restore
**/packages/*
+
# except build/, which is used as an MSBuild target.
!**/packages/build/
+
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
@@ -255,3 +259,12 @@ paket-files/
*.sln.iml
PublishProfiles
+/.vscode
+launchSettings.json
+/coverages
+**/.DS_Store
+
+# Benchmarks
+**/BenchmarkDotNet.Artifacts/
+/src/Neo.CLI/neo-cli/
+**/localnet_nodes/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 772858f229..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-language: csharp
-
-os:
- - linux
- - osx
-
-dist: trusty
-osx_image: xcode9.1
-
-mono: none
-dotnet: 2.0.0
-
-before_install:
- - cd neo.UnitTests
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ulimit -n 2048; fi
-
-script:
- - dotnet restore
- - dotnet test
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..5fd0592924
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,82 @@
+
+# Contributing to NEO
+Neo is an open-source project and it depends on its contributors and constant community feedback to implement the features required for a smart economy. You are more than welcome to join us in the development of Neo.
+
+Read this document to understand how issues are organized and how you can start contributing.
+
+*This document covers this repository only and does not include community repositories or repositories managed by NGD Shanghai and NGD Seattle.*
+
+### Questions and Support
+The issue list is reserved exclusively for bug reports and features discussions. If you have questions or need support, please visit us in our [Discord](https://discord.io/neo) server.
+
+### dApp Development
+This document does not relate to dApp development. If you are looking to build a dApp using Neo, please [start here](https://neo.org/dev).
+
+### Contributing to open source projects
+If you are new to open-source development, please [read here](https://opensource.guide/how-to-contribute/#opening-a-pull-request) how to submit your code.
+
+## Developer Guidance
+We try to have as few rules as possible, just enough to keep the project organized:
+
+
+1. **Discuss before coding**. Proposals must be discussed before being implemented.
+Avoid implementing issues with the discussion tag.
+2. **Tests during code review**. We expect reviewers to test the issue before approving or requesting changes.
+
+3. **Wait for at least 2 reviews before merging**. Changes can be merged after 2 approvals, for Neo 3.x branch, and 3 approvals for Neo 2.x branch.
+
+3. **Give time to other developers review an issue**. Even if the code has been approved, you should leave at least 24 hours for others to review it before merging the code.
+
+4. **Create unit tests**. It is important that the developer includes basic unit tests so reviewers can test it.
+
+5. **Task assignment**. If a developer wants to work in a specific issue, he may ask the team to assign it to himself. The proposer of an issue has priority in task assignment.
+
+
+### Issues for beginners
+If you are looking to start contributing to NEO, we suggest you start working on issues with  or  tags since they usually do not depend on extensive NEO platform knowledge.
+
+### Tags for Issues States
+
+ Whenever someone posts a new feature request, the tag discussion is added. This means that there is no consensus if the feature should be implemented or not. Avoid creating PR to solve issues in this state since it may be completely discarded.
+
+ When a feature request is accepted by the team, but there is no consensus about the implementation, the issue is tagged with design. We recommend the team to agree in the solution design before anyone attempts to implement it, using text or UML. It is not recommended, but developers can also present their solution using code.
+Note that PRs for issues in this state may also be discarded if the team disagree with the proposed solution.
+
+ Once the team has agreed on feature and the proposed solution, the issue is tagged with ready-to-implement. When implementing it, please follow the solution accepted by the team.
+
+### Tags for Issue Types
+
+ Issues with the cosmetic tag are usually changes in code or documentation that improve user experience without affecting current functionality. These issues are recommended for beginners because they require little to no knowledge about Neo platform.
+
+ Enhancements are platform changes that may affect performance, usability or add new features to existing modules. It is recommended that developers have previous knowledge in the platform to work in these improvements, specially in more complicated modules like the compiler, ledger and consensus.
+
+ New features may include large changes in the code base. Some are complex, but some are not. So, a few issues with new-feature may be recommended for starters, specially those related to the rpc and the sdk module.
+
+ Issues related to the migration from Neo 2 to Neo 3 are tagged with migration. These issues are usually the most complicated ones since they require a deep knowledge in both versions.
+
+### Tags for Project Modules
+These tags do not necessarily represent each module at code level. Modules consensus and compiler are not recommended for beginners.
+
+ Issues that are related or influence the behavior of our C# compiler. Note that the compiler itself is hosted in the [neo-devpack-dotnet](https://github.com/neo-project/neo-devpack-dotnet) repository.
+
+ Changes to consensus are usually harder to make and test. Avoid implementing issues in this module that are not yet decided.
+
+ The ledger is our 'database', any changes in the way we store information or the data-structures have this tag.
+
+ 'Small' enhancements that need to be done in order to keep the project organised and ensure overall quality. These changes may be applied in any place in code, as long as they are small or do not alter current behavior.
+
+ Identify issues that affect the network-policy like fees, access list or other related issues. Voting may also be related to the network policy module.
+
+ This module includes peer-to-peer message exchange and network optimisations, at TCP or UDP level (not HTTP).
+
+ All HTTP communication is handled by the RPC module. This module usually provides support methods since the main communication protocol takes place at the p2p module.
+
+ New features that affect the Neo Virtual Machine or the Interop layer.
+
+ Neo provides an SDK to help developers to interact with the blockchain. Changes in this module must not impact other parts of the software.
+
+ Wallets are used to track funds and interact with the blockchain. Note that this module depends on a full node implementation (data stored on local disk).
+
+
+
+
diff --git a/README.md b/README.md
index a1d7fe9f0d..bd05fb7f08 100644
--- a/README.md
+++ b/README.md
@@ -1,72 +1,201 @@
-NEO: A distributed network for the Smart Economy
-================
+
+
+
+
+
+
+CSharp implementation of the neo blockchain protocol.
+
+
+ A modern distributed network for the Smart Economy.
+
+ Documentation »
+
+
+ Neo
+ ·
+ Neo Modules
+ ·
+ Neo DevPack
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Table of Contents
+1. [Overview](#overview)
+2. [Project structure](#project-structure)
+3. [Related projects](#related-projects)
+4. [Opening a new issue](#opening-a-new-issue)
+5. [Contributing](#contributing)
+6. [Bounty program](#bounty-program)
+7. [License](#license)
+
+## Overview
+This repository is a csharp implementation of the [neo](https://neo.org) blockchain. It is jointly maintained by the neo core developers and neo global development community.
+Visit the [tutorials](https://docs.neo.org) to get started.
+
+
+## Project structure
+An overview of the project folders can be seen below.
+
+|Folder|Content|
+|---|---|
+|[/src/neo/Cryptography/](https://github.com/neo-project/neo/tree/master/src/Neo/Cryptography)|General cryptography implementation, including ECC.|
+|[/src/neo/IO/](https://github.com/neo-project/neo/tree/master/src/Neo/IO)|Data structures used for caching and collection interaction.|
+|[/src/neo/Ledger/](https://github.com/neo-project/neo/tree/master/src/Neo/Ledger)|Classes responsible for the state control, including the `MemoryPool` and `Blockchain`.|
+|[/src/neo/Network/](https://github.com/neo-project/neo/tree/master/src/Neo/Network)|Peer-to-peer protocol implementation.|
+|[/src/neo/Persistence/](https://github.com/neo-project/neo/tree/master/src/Neo/Persistence)|Classes used to allow other classes to access application state.|
+|[/src/neo/Plugins/](https://github.com/neo-project/neo/tree/master/src/Neo/Plugins)|Interfaces used to extend Neo, including the storage interface.|
+|[/src/neo/SmartContract/](https://github.com/neo-project/neo/tree/master/src/Neo/SmartContract)|Native contracts, `ApplicationEngine`, `InteropService` and other smart-contract related classes.|
+|[/src/neo/Wallets/](https://github.com/neo-project/neo/tree/master/src/Neo/Wallets)|Wallet and account implementation.|
+|[/src/Neo.Extensions/](https://github.com/neo-project/neo/tree/master/src/Neo.Extensions)| Extensions to expand the existing functionality.|
+|[/src/Neo.Json/](https://github.com/neo-project/neo/tree/master/src/Neo.Json)| Neo's JSON specification.|
+|[/tests/](https://github.com/neo-project/neo/tree/master/tests)|All unit tests.|
+
+## Related projects
+Code references are provided for all platform building blocks. That includes the base library, the VM, a command line application and the compiler.
+
+* [neo:](https://github.com/neo-project/neo/) Included libraries are Neo, Neo-CLI, Neo-GUI, Neo-VM, test and plugin modules.
+* [neo-express:](https://github.com/neo-project/neo-express/) A private net optimized for development scenarios.
+* [neo-devpack-dotnet:](https://github.com/neo-project/neo-devpack-dotnet/) These are the official tools used to convert a C# smart-contract into a *neo executable file*.
+* [neo-proposals:](https://github.com/neo-project/proposals) NEO Enhancement Proposals (NEPs) describe standards for the NEO platform, including core protocol specifications, client APIs, and contract standards.
+* [neo-non-native-contracts:](https://github.com/neo-project/non-native-contracts) Includes non-native contracts that live on the blockchain, included but not limited to NeoNameService.
+
+## Opening a new issue
+Please feel free to create new issues to suggest features or ask questions.
+
+- [Feature request](https://github.com/neo-project/neo/issues/new?assignees=&labels=discussion&template=feature-or-enhancement-request.md&title=)
+- [Bug report](https://github.com/neo-project/neo/issues/new?assignees=&labels=&template=bug_report.md&title=)
+- [Questions](https://github.com/neo-project/neo/issues/new?assignees=&labels=question&template=questions.md&title=)
+
+If you found a security issue, please refer to our [security policy](https://github.com/neo-project/neo/security/policy).
+
+## Contributing
+
+We welcome contributions to the Neo project! To ensure a smooth collaboration process, please follow these guidelines:
+
+### Branch Rules
+
+- **`master`** - Contains the latest stable release version. This branch reflects the current production state.
+- **`dev`** - The main development branch where all new features and improvements are integrated.
+
+### Pull Request Guidelines
+
+**Important**: All pull requests must be based on the `dev` branch, not `master`.
+
+1. **Fork the repository** and create your feature branch from `dev`:
+ ```bash
+ git checkout dev
+ git pull origin dev
+ git checkout -b feature/your-feature-name
+ ```
+
+2. **Make your changes** following the project's coding standards and conventions.
+
+3. **Test your changes** thoroughly to ensure they don't break existing functionality.
+
+4. **Commit your changes** with clear, descriptive commit messages:
+ ```bash
+ git commit -m "feat: add new feature description"
+ ```
+
+5. **Push to your fork** and create a pull request against the `dev` branch:
+ ```bash
+ git push origin feature/your-feature-name
+ ```
+
+6. **Create a Pull Request** targeting the `dev` branch with:
+ - Clear title and description
+ - Reference to any related issues
+ - Summary of changes made
-NEO uses digital identity and blockchain technology to digitize assets and leverages smart contracts for autonomously managed digital assets to create a "smart economy" within a decentralized network.
-
-To learn more about NEO, please read the [White Paper](http://docs.neo.org/en-us/index.html)|[白皮书](http://docs.neo.org/zh-cn/index.html).
-
-Supported Platforms
---------
-
-We already support the following platforms:
-
-* CentOS 7
-* Docker
-* macOS 10 +
-* Red Hat Enterprise Linux 7.0 +
-* Ubuntu 14.04, Ubuntu 14.10, Ubuntu 15.04, Ubuntu 15.10, Ubuntu 16.04, Ubuntu 16.10
-* Windows 7 SP1 +, Windows Server 2008 R2 +
-
-We will support the following platforms in the future:
-
-* Debian
-* Fedora
-* FreeBSD
-* Linux Mint
-* OpenSUSE
-* Oracle Linux
-
-Development
---------
-
-To start building peer applications for NEO on Windows, you need to download [Visual Studio 2017](https://www.visualstudio.com/products/visual-studio-community-vs) and install the [.NET Core SDK](https://www.microsoft.com/net/core).
-
-If you need to develop on Linux or macOS, just install the [.NET Core SDK](https://www.microsoft.com/net/core).
-
-To install Neo SDK to your project, run the following command in the [Package Manager Console](https://docs.nuget.org/ndocs/tools/package-manager-console):
+### Development Workflow
```
-PM> Install-Package Neo
+feature/bug-fix → dev → master (via release)
```
-For more information about how to build DAPPs for NEO, please read the [documentation](http://docs.neo.org/en-us/sc/introduction.html)|[文档](http://docs.neo.org/zh-cn/sc/introduction.html).
-
-How to Contribute
---------
-
-You can contribute to NEO with [issues](https://github.com/neo-project/neo/issues) and [PRs](https://github.com/neo-project/neo/pulls). Simply filing issues for problems you encounter is a great way to contribute. Contributing implementations is greatly appreciated.
-
-We use and recommend the following workflow:
-
-1. Create an issue for your work.
- * You can skip this step for trivial changes.
- * Reuse an existing issue on the topic, if there is one.
- * Clearly state that you are going to take on implementing it, if that's the case. You can request that the issue be assigned to you. Note: The issue filer and the implementer don't have to be the same person.
-1. Create a personal fork of the repository on GitHub (if you don't already have one).
-1. Create a branch off of master(`git checkout -b mybranch`).
- * Name the branch so that it clearly communicates your intentions, such as issue-123 or githubhandle-issue.
- * Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
-1. Make and commit your changes.
-1. Add new tests corresponding to your change, if applicable.
-1. Build the repository with your changes.
- * Make sure that the builds are clean.
- * Make sure that the tests are all passing, including your new tests.
-1. Create a pull request (PR) against the upstream repository's master branch.
- * Push your changes to your fork on GitHub.
+- Feature branches are merged into `dev`
+- `dev` is periodically merged into `master` for releases
+- Never create PRs directly against `master`
-Note: It is OK for your PR to include a large number of commits. Once your change is accepted, you will be asked to squash your commits into one or some appropriately small number of commits before your PR is merged.
+For more detailed contribution guidelines, please check our documentation or reach out to the maintainers.
-License
-------
+## Bounty program
+You can be rewarded by finding security issues. Please refer to our [bounty program page](https://neo.org/bounty) for more information.
+## License
The NEO project is licensed under the [MIT license](LICENSE).
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000000..24894d5e9a
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,13 @@
+# Security Policy
+
+The purpose of NEO vulnerability bounty program is to be proactive about blockchain security by providing a channel for security researchers to report potential security vulnerabilities identified related to our underlying infrastructure.
+
+First, it is recommended to read the following page https://neo.org/dev/bounty, if you find a security vulnerability in NEO, please report it as indicated on that page.
+
+Please withhold public disclosure until the security team has addressed the vulnerability and it has been solved.
+
+We appreciate your efforts to responsibly disclose your findings, and we will make every effort to acknowledge your contributions.
+
+The security team will acknowledge your email within 5 business days. You will receive a more detailed response within 10 business days.
+
+When in doubt, please do send us a report.
diff --git a/SpellingExclusions.dic b/SpellingExclusions.dic
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/benchmarks/Directory.Build.props b/benchmarks/Directory.Build.props
new file mode 100644
index 0000000000..23182611c1
--- /dev/null
+++ b/benchmarks/Directory.Build.props
@@ -0,0 +1,16 @@
+
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+ false
+
+
+
+
+
+
+
diff --git a/benchmarks/Neo.Benchmarks/Benchmarks.Hash.cs b/benchmarks/Neo.Benchmarks/Benchmarks.Hash.cs
new file mode 100644
index 0000000000..36ce30108b
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/Benchmarks.Hash.cs
@@ -0,0 +1,55 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmarks.Hash.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+using Neo.Cryptography;
+using System.Diagnostics;
+using System.IO.Hashing;
+using System.Text;
+
+namespace Neo.Benchmarks;
+
+public class Benchmarks_Hash
+{
+ // 256 KiB
+ static readonly byte[] data = Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat("Hello, World!^_^", 16 * 1024)));
+
+ static readonly byte[] hash = "9182abedfbb9b18d81a05d8bcb45489e7daa2858".HexToBytes();
+
+ [Benchmark]
+ public static void XxHash32_HashToUInt32()
+ {
+ var result = XxHash32.HashToUInt32(data);
+ Debug.Assert(result == 682967318u);
+ }
+
+ [Benchmark]
+ public static void XxHash3_HashToUInt64()
+ {
+ var result = (uint)XxHash3.HashToUInt64(data);
+ Debug.Assert(result == 1389469485u);
+ }
+
+ [Benchmark]
+ public static void Murmur32_HashToUInt32()
+ {
+ var result = data.Murmur32(0);
+ Debug.Assert(result == 3731881930u);
+ }
+
+ [Benchmark]
+ public static void Murmur128_ComputeHash()
+ {
+ var result = data.Murmur128(0);
+ if (result.Length != 16)
+ throw new InvalidOperationException($"Invalid hash length {result.Length}");
+ }
+}
diff --git a/benchmarks/Neo.Benchmarks/Benchmarks.POC.cs b/benchmarks/Neo.Benchmarks/Benchmarks.POC.cs
new file mode 100644
index 0000000000..08a134512d
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/Benchmarks.POC.cs
@@ -0,0 +1,78 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmarks.POC.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+using Neo.Network.P2P.Payloads;
+using Neo.SmartContract;
+using Neo.VM;
+using System.Diagnostics;
+
+namespace Neo.Benchmarks;
+
+public class Benchmarks_PoCs
+{
+ private static readonly ProtocolSettings protocol = ProtocolSettings.Load("config.json");
+ private static readonly NeoSystem system = new(protocol, (string?)null);
+
+ [Benchmark]
+ public void NeoIssue2725()
+ {
+ // https://github.com/neo-project/neo/issues/2725
+ // L00: INITSSLOT 1
+ // L01: NEWARRAY0
+ // L02: PUSHDATA1 6161616161 //"aaaaa"
+ // L03: PUSHINT16 500
+ // L04: STSFLD0
+ // L05: OVER
+ // L06: OVER
+ // L07: SYSCALL 95016f61 //System.Runtime.Notify
+ // L08: LDSFLD0
+ // L09: DEC
+ // L10: DUP
+ // L11: STSFLD0
+ // L12: JMPIF L05
+ // L13: CLEAR
+ // L14: SYSCALL dbfea874 //System.Runtime.GetExecutingScriptHash
+ // L15: PUSHINT16 8000
+ // L16: STSFLD0
+ // L17: DUP
+ // L18: SYSCALL 274335f1 //System.Runtime.GetNotifications
+ // L19: DROP
+ // L20: LDSFLD0
+ // L21: DEC
+ // L22: DUP
+ // L23: STSFLD0
+ // L24: JMPIF L17
+ Run(nameof(NeoIssue2725), "VgHCDAVhYWFhYQH0AWBLS0GVAW9hWJ1KYCT1SUHb/qh0AUAfYEpBJ0M18UVYnUpgJPU=");
+ }
+
+ private static void Run(string name, string poc)
+ {
+ Random random = new();
+ Transaction tx = new()
+ {
+ Version = 0,
+ Nonce = (uint)random.Next(),
+ SystemFee = 20_00000000,
+ NetworkFee = 1_00000000,
+ ValidUntilBlock = ProtocolSettings.Default.MaxTraceableBlocks,
+ Signers = Array.Empty(),
+ Attributes = Array.Empty(),
+ Script = Convert.FromBase64String(poc),
+ Witnesses = Array.Empty()
+ };
+ using var snapshot = system.GetSnapshotCache();
+ using var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, system.GenesisBlock, protocol, tx.SystemFee);
+ engine.LoadScript(tx.Script);
+ engine.Execute();
+ Debug.Assert(engine.State == VMState.FAULT);
+ }
+}
diff --git a/benchmarks/Neo.Benchmarks/Benchmarks.SignData.cs b/benchmarks/Neo.Benchmarks/Benchmarks.SignData.cs
new file mode 100644
index 0000000000..f0c6be93c1
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/Benchmarks.SignData.cs
@@ -0,0 +1,56 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmarks.SignData.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+using Neo.Extensions.IO;
+using Neo.Network.P2P;
+using Neo.Network.P2P.Payloads;
+
+namespace Neo.Benchmarks;
+
+public class Benchmarks_SignData
+{
+ private static readonly Transaction s_tx = new()
+ {
+ Attributes = [],
+ Script = Array.Empty(),
+ Signers = [new Signer() { Account = UInt160.Zero, AllowedContracts = [], AllowedGroups = [], Rules = [], Scopes = WitnessScope.Global }],
+ Witnesses = []
+ };
+
+ ///
+ /// Gets the data of a object to be hashed.
+ ///
+ /// The object to hash.
+ /// The magic number of the network.
+ /// The data to hash.
+ public static byte[] GetSignDataV1(IVerifiable verifiable, uint network)
+ {
+ using MemoryStream ms = new();
+ using BinaryWriter writer = new(ms);
+ writer.Write(network);
+ writer.Write(verifiable.Hash);
+ writer.Flush();
+ return ms.ToArray();
+ }
+
+ [Benchmark]
+ public static void TestOld()
+ {
+ GetSignDataV1(s_tx, 0);
+ }
+
+ [Benchmark]
+ public static void TestNew()
+ {
+ s_tx.GetSignData(0);
+ }
+}
diff --git a/benchmarks/Neo.Benchmarks/Benchmarks.UInt160.cs b/benchmarks/Neo.Benchmarks/Benchmarks.UInt160.cs
new file mode 100644
index 0000000000..091dda8f68
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/Benchmarks.UInt160.cs
@@ -0,0 +1,86 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmarks.UInt160.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+
+namespace Neo.Benchmarks;
+
+public class Benchmarks_UInt160
+{
+ static readonly UInt160 s_newUInt160 = new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
+
+ [Benchmark]
+ public static void TestGernerator1()
+ {
+ _ = new UInt160();
+ }
+
+ [Benchmark]
+ public static void TestGernerator2()
+ {
+ _ = new UInt160(new byte[20]);
+ }
+
+ [Benchmark]
+ public static void TestCompareTo()
+ {
+ UInt160.Zero.CompareTo(UInt160.Zero);
+ UInt160.Zero.CompareTo(s_newUInt160);
+ s_newUInt160.CompareTo(UInt160.Zero);
+ }
+
+ [Benchmark]
+ public static void TestEquals()
+ {
+ UInt160.Zero.Equals(UInt160.Zero);
+ UInt160.Zero.Equals(s_newUInt160);
+ s_newUInt160.Equals(null);
+ }
+
+ [Benchmark]
+ public static void TestParse()
+ {
+ _ = UInt160.Parse("0x0000000000000000000000000000000000000000");
+ _ = UInt160.Parse("0000000000000000000000000000000000000000");
+ }
+
+ [Benchmark]
+ public static void TestTryParse()
+ {
+ _ = UInt160.TryParse("0x0000000000000000000000000000000000000000", out _);
+ _ = UInt160.TryParse("0x1230000000000000000000000000000000000000", out _);
+ _ = UInt160.TryParse("000000000000000000000000000000000000000", out _);
+ }
+
+ [Benchmark]
+ public static void TestOperatorLarger()
+ {
+ _ = s_newUInt160 > UInt160.Zero;
+ }
+
+ [Benchmark]
+ public static void TestOperatorLargerAndEqual()
+ {
+ _ = s_newUInt160 >= UInt160.Zero;
+ }
+
+ [Benchmark]
+ public static void TestOperatorSmaller()
+ {
+ _ = s_newUInt160 < UInt160.Zero;
+ }
+
+ [Benchmark]
+ public static void TestOperatorSmallerAndEqual()
+ {
+ _ = s_newUInt160 <= UInt160.Zero;
+ }
+}
diff --git a/benchmarks/Neo.Benchmarks/IO/Benchmarks.Cache.cs b/benchmarks/Neo.Benchmarks/IO/Benchmarks.Cache.cs
new file mode 100644
index 0000000000..04959aa0f9
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/IO/Benchmarks.Cache.cs
@@ -0,0 +1,130 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmarks.Cache.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+using Neo.IO.Caching;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace Neo.Benchmarks.IO;
+
+class BenchmarkFIFOCache : FIFOCache
+{
+ public BenchmarkFIFOCache(int maxCapacity) : base(maxCapacity) { }
+
+ protected override long GetKeyForItem(long item) => item;
+}
+
+class BenchmarkKeyedCollectionSlim : KeyedCollectionSlim
+{
+ public BenchmarkKeyedCollectionSlim(int capacity) : base(capacity) { }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ protected override long GetKeyForItem(long item) => item;
+}
+
+public class Benchmarks_Cache
+{
+ const int CacheSize = 1000;
+
+ private readonly BenchmarkFIFOCache _cache = new(CacheSize);
+
+ private readonly HashSetCache _hashSetCache = new(CacheSize);
+
+ private long[] _items = [];
+
+ [Params(1000, 10000)]
+ public int OperationCount { get; set; }
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ // Initialize cache with some data
+ for (int i = 0; i < CacheSize; i++)
+ {
+ _cache.Add(i);
+ }
+ }
+
+ [Benchmark]
+ public void FIFOCacheAdd()
+ {
+ for (int i = 0; i < OperationCount; i++)
+ {
+ _cache.Add(i);
+ }
+ }
+
+ [Benchmark]
+ public void FIFOCacheContains()
+ {
+ for (long i = 0; i < OperationCount; i++)
+ {
+ var ok = _cache.TryGet(i, out _);
+ Debug.Assert(ok);
+ }
+ }
+
+ [Benchmark]
+ public void KeyedCollectionSlimAdd()
+ {
+ var keyed = new BenchmarkKeyedCollectionSlim(CacheSize);
+ for (int i = 0; i < OperationCount; i++)
+ {
+ keyed.TryAdd(i);
+ }
+ }
+
+ [Benchmark]
+ public void KeyedCollectionSlimMixed()
+ {
+ var keyed = new BenchmarkKeyedCollectionSlim(CacheSize);
+ for (long i = 0; i < OperationCount; i++)
+ {
+ keyed.TryAdd(i);
+
+ var ok = keyed.Contains(i);
+ Debug.Assert(ok);
+ }
+
+ for (long i = 0; i < OperationCount; i++)
+ {
+ var ok = keyed.Remove(i);
+ Debug.Assert(ok);
+ }
+ }
+
+ [GlobalSetup(Target = nameof(HashSetCache))]
+ public void SetupHashSetCache()
+ {
+ _items = new long[OperationCount];
+ for (int i = 0; i < OperationCount; i++)
+ {
+ _items[i] = i;
+ }
+ }
+
+ [Benchmark]
+ public void HashSetCache()
+ {
+ for (int i = 0; i < OperationCount; i++)
+ {
+ var ok = _hashSetCache.TryAdd(i);
+ Debug.Assert(ok);
+ }
+ if (_hashSetCache.Count != CacheSize)
+ throw new Exception($"HashSetCacheAdd: {_hashSetCache.Count}");
+
+ _hashSetCache.ExceptWith(_items);
+ if (_hashSetCache.Count > 0)
+ throw new Exception($"HashSetCacheExceptWith: {_hashSetCache.Count}");
+ }
+}
diff --git a/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj b/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj
new file mode 100644
index 0000000000..3138e58bad
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/Neo.Benchmarks.csproj
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+ PreserveNewest
+ PreserveNewest
+
+
+
+
diff --git a/benchmarks/Neo.Benchmarks/Program.cs b/benchmarks/Neo.Benchmarks/Program.cs
new file mode 100644
index 0000000000..16255a17ee
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/Program.cs
@@ -0,0 +1,23 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Program.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Running;
+
+// List all benchmarks:
+// dotnet run -c Release --framework [for example: net9.0] -- --list flat(or tree)
+// Run a specific benchmark:
+// dotnet run -c Release --framework [for example: net9.0] -- -f [benchmark name]
+// Run all benchmarks:
+// dotnet run -c Release --framework [for example: net9.0] -- -f *
+// Run all benchmarks of a class:
+// dotnet run -c Release --framework [for example: net9.0] -- -f '*Class*'
+// More options: https://benchmarkdotnet.org/articles/guides/console-args.html
+BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
diff --git a/benchmarks/Neo.Benchmarks/SmartContract/Benchmarks.StorageKey.cs b/benchmarks/Neo.Benchmarks/SmartContract/Benchmarks.StorageKey.cs
new file mode 100644
index 0000000000..a890dc7c37
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/SmartContract/Benchmarks.StorageKey.cs
@@ -0,0 +1,62 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmarks.StorageKey.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+using Neo.SmartContract;
+using System.Text;
+
+namespace Neo.Benchmarks.SmartContract;
+
+public class Benchmarks_StorageKey
+{
+ // for avoiding overhead of encoding
+ private static readonly byte[] testBytes = Encoding.ASCII.GetBytes("StorageKey");
+
+ private const int prefixSize = sizeof(int) + sizeof(byte);
+
+ [Benchmark]
+ public static void KeyBuilder_AddInt()
+ {
+ var key = new KeyBuilder(1, 0)
+ .Add(1)
+ .Add(2)
+ .Add(3);
+
+ var bytes = key.ToArray();
+ if (bytes.Length != prefixSize + 3 * sizeof(int))
+ throw new InvalidOperationException();
+ }
+
+ [Benchmark]
+ public static void KeyBuilder_AddBytes()
+ {
+ var key = new KeyBuilder(1, 0)
+ .Add(testBytes)
+ .Add(testBytes)
+ .Add(testBytes);
+
+ var bytes = key.ToArray();
+ if (bytes.Length != prefixSize + 3 * testBytes.Length)
+ throw new InvalidOperationException();
+ }
+
+ [Benchmark]
+ public void KeyBuilder_AddUInt160()
+ {
+ Span value = stackalloc byte[UInt160.Length];
+ var key = new KeyBuilder(1, 0)
+ .Add(new UInt160(value));
+
+ var bytes = key.ToArray();
+ if (bytes.Length != prefixSize + UInt160.Length)
+ throw new InvalidOperationException();
+ }
+}
diff --git a/benchmarks/Neo.Benchmarks/config.json b/benchmarks/Neo.Benchmarks/config.json
new file mode 100644
index 0000000000..01471e4c76
--- /dev/null
+++ b/benchmarks/Neo.Benchmarks/config.json
@@ -0,0 +1,71 @@
+{
+ "ApplicationConfiguration": {
+ "Logger": {
+ "Path": "Logs",
+ "ConsoleOutput": false,
+ "Active": false
+ },
+ "Storage": {
+ "Engine": "LevelDBStore", // Candidates [MemoryStore, LevelDBStore, RocksDBStore]
+ "Path": "Data_LevelDB_{0}" // {0} is a placeholder for the network id
+ },
+ "P2P": {
+ "Port": 10333,
+ "MinDesiredConnections": 10,
+ "MaxConnections": 40,
+ "MaxConnectionsPerAddress": 3
+ },
+ "UnlockWallet": {
+ "Path": "",
+ "Password": "",
+ "IsActive": false
+ },
+ "Contracts": {
+ "NeoNameService": "0x50ac1c37690cc2cfc594472833cf57505d5f46de"
+ }
+ },
+ "ProtocolConfiguration": {
+ "Network": 860833102,
+ "AddressVersion": 53,
+ "MillisecondsPerBlock": 15000,
+ "MaxTransactionsPerBlock": 512,
+ "MemoryPoolMaxTransactions": 50000,
+ "MaxTraceableBlocks": 2102400,
+ "Hardforks": {
+ "HF_Aspidochelone": 1730000,
+ "HF_Basilisk": 4120000
+ },
+ "InitialGasDistribution": 5200000000000000,
+ "ValidatorsCount": 7,
+ "StandbyCommittee": [
+ "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c",
+ "02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093",
+ "03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a",
+ "02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554",
+ "024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d",
+ "02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e",
+ "02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70",
+ "023a36c72844610b4d34d1968662424011bf783ca9d984efa19a20babf5582f3fe",
+ "03708b860c1de5d87f5b151a12c2a99feebd2e8b315ee8e7cf8aa19692a9e18379",
+ "03c6aa6e12638b36e88adc1ccdceac4db9929575c3e03576c617c49cce7114a050",
+ "03204223f8c86b8cd5c89ef12e4f0dbb314172e9241e30c9ef2293790793537cf0",
+ "02a62c915cf19c7f19a50ec217e79fac2439bbaad658493de0c7d8ffa92ab0aa62",
+ "03409f31f0d66bdc2f70a9730b66fe186658f84a8018204db01c106edc36553cd0",
+ "0288342b141c30dc8ffcde0204929bb46aed5756b41ef4a56778d15ada8f0c6654",
+ "020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639",
+ "0222038884bbd1d8ff109ed3bdef3542e768eef76c1247aea8bc8171f532928c30",
+ "03d281b42002647f0113f36c7b8efb30db66078dfaaa9ab3ff76d043a98d512fde",
+ "02504acbc1f4b3bdad1d86d6e1a08603771db135a73e61c9d565ae06a1938cd2ad",
+ "0226933336f1b75baa42d42b71d9091508b638046d19abd67f4e119bf64a7cfb4d",
+ "03cdcea66032b82f5c30450e381e5295cae85c5e6943af716cc6b646352a6067dc",
+ "02cd5a5547119e24feaa7c2a0f37b8c9366216bab7054de0065c9be42084003c8a"
+ ],
+ "SeedList": [
+ "seed1.neo.org:10333",
+ "seed2.neo.org:10333",
+ "seed3.neo.org:10333",
+ "seed4.neo.org:10333",
+ "seed5.neo.org:10333"
+ ]
+ }
+}
diff --git a/benchmarks/Neo.Extensions.Benchmarks/Benchmark.ByteArrayComparer.cs b/benchmarks/Neo.Extensions.Benchmarks/Benchmark.ByteArrayComparer.cs
new file mode 100644
index 0000000000..650cf476dc
--- /dev/null
+++ b/benchmarks/Neo.Extensions.Benchmarks/Benchmark.ByteArrayComparer.cs
@@ -0,0 +1,95 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmark.ByteArrayComparer.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+
+namespace Neo.Extensions.Benchmarks;
+
+public class Benchmark_ByteArrayComparer
+{
+ private ByteArrayComparer comparer = ByteArrayComparer.Default;
+
+ private byte[]? x, y;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ comparer = ByteArrayComparer.Default;
+ }
+
+ [GlobalSetup(Target = nameof(NewCompare_50Bytes))]
+ public void SetupNew50Bytes()
+ {
+ comparer = ByteArrayComparer.Default;
+
+ x = new byte[50]; // 50 bytes
+ y = new byte[50]; // 50 bytes
+ Array.Fill(x, (byte)0xCC);
+ Array.Copy(x, y, x.Length);
+ }
+
+ [Benchmark]
+ public void NewCompare_50Bytes()
+ {
+ comparer.Compare(x, y);
+ }
+
+ [GlobalSetup(Target = nameof(NewCompare_500Bytes))]
+ public void SetupNew500Bytes()
+ {
+ comparer = ByteArrayComparer.Default;
+
+ x = new byte[500]; // 500 bytes
+ y = new byte[500]; // 500 bytes
+ Array.Fill(x, (byte)0xCC);
+ Array.Copy(x, y, x.Length);
+ }
+
+ [Benchmark]
+ public void NewCompare_500Bytes()
+ {
+ comparer.Compare(x, y);
+ }
+
+ [GlobalSetup(Target = nameof(NewCompare_5000Bytes))]
+ public void SetupNew5000Bytes()
+ {
+ comparer = ByteArrayComparer.Default;
+
+ x = new byte[5000]; // 5000 bytes
+ y = new byte[5000]; // 5000 bytes
+ Array.Fill(x, (byte)0xCC);
+ Array.Copy(x, y, x.Length);
+ }
+
+ [Benchmark]
+ public void NewCompare_5000Bytes()
+ {
+ comparer.Compare(x, y);
+ }
+
+ [GlobalSetup(Target = nameof(NewCompare_50000Bytes))]
+ public void SetupNew50000Bytes()
+ {
+ comparer = ByteArrayComparer.Default;
+
+ x = new byte[50000]; // 50000 bytes
+ y = new byte[50000]; // 50000 bytes
+ Array.Fill(x, (byte)0xCC);
+ Array.Copy(x, y, x.Length);
+ }
+
+ [Benchmark]
+ public void NewCompare_50000Bytes()
+ {
+ comparer.Compare(x, y);
+ }
+}
diff --git a/benchmarks/Neo.Extensions.Benchmarks/Benchmark.StringExtensions.cs b/benchmarks/Neo.Extensions.Benchmarks/Benchmark.StringExtensions.cs
new file mode 100644
index 0000000000..766c820200
--- /dev/null
+++ b/benchmarks/Neo.Extensions.Benchmarks/Benchmark.StringExtensions.cs
@@ -0,0 +1,27 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmark.StringExtensions.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+
+namespace Neo.Extensions.Benchmarks;
+
+public class Benchmark_StringExtensions
+{
+ private const string _testHex = "0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1e1f20";
+
+ [Benchmark]
+ public static void HexToBytes()
+ {
+ var bytes = _testHex.HexToBytes();
+ if (bytes.Length != 32)
+ throw new Exception("Invalid length");
+ }
+}
diff --git a/benchmarks/Neo.Extensions.Benchmarks/Neo.Extensions.Benchmarks.csproj b/benchmarks/Neo.Extensions.Benchmarks/Neo.Extensions.Benchmarks.csproj
new file mode 100644
index 0000000000..954272b073
--- /dev/null
+++ b/benchmarks/Neo.Extensions.Benchmarks/Neo.Extensions.Benchmarks.csproj
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/benchmarks/Neo.Extensions.Benchmarks/Program.cs b/benchmarks/Neo.Extensions.Benchmarks/Program.cs
new file mode 100644
index 0000000000..16255a17ee
--- /dev/null
+++ b/benchmarks/Neo.Extensions.Benchmarks/Program.cs
@@ -0,0 +1,23 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Program.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Running;
+
+// List all benchmarks:
+// dotnet run -c Release --framework [for example: net9.0] -- --list flat(or tree)
+// Run a specific benchmark:
+// dotnet run -c Release --framework [for example: net9.0] -- -f [benchmark name]
+// Run all benchmarks:
+// dotnet run -c Release --framework [for example: net9.0] -- -f *
+// Run all benchmarks of a class:
+// dotnet run -c Release --framework [for example: net9.0] -- -f '*Class*'
+// More options: https://benchmarkdotnet.org/articles/guides/console-args.html
+BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
diff --git a/benchmarks/Neo.Json.Benchmarks/Benchmark_JBoolean.cs b/benchmarks/Neo.Json.Benchmarks/Benchmark_JBoolean.cs
new file mode 100644
index 0000000000..3026753d47
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Benchmark_JBoolean.cs
@@ -0,0 +1,55 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmark_JBoolean.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+
+namespace Neo.Json.Benchmarks;
+
+[MemoryDiagnoser]
+[CsvMeasurementsExporter]
+[MarkdownExporter]
+public class Benchmark_JBoolean
+{
+ private JBoolean _jFalse = new();
+ private JBoolean _jTrue = new(true);
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _jFalse = new JBoolean();
+ _jTrue = new JBoolean(true);
+ }
+
+ [Benchmark]
+ public void TestAsNumber()
+ {
+ _ = _jFalse.AsNumber();
+ _ = _jTrue.AsNumber();
+ }
+
+ [Benchmark]
+ public void TestConversionToString()
+ {
+ _ = _jTrue.ToString();
+ _ = _jFalse.ToString();
+ }
+}
+
+/// BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2605)
+/// 13th Gen Intel Core i9-13900H, 1 CPU, 20 logical and 14 physical cores
+/// .NET SDK 9.0.101
+/// [Host] : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2 [AttachedDebugger]
+/// DefaultJob: .NET 9.0.0(9.0.24.52809), X64 RyuJIT AVX2
+///
+/// | Method | Mean | Error | StdDev | Median | Gen0 | Allocated |
+/// |----------------------- |-----------:|----------:|----------:|-----------:|-------:|----------:|
+/// | TestAsNumber | 0.0535 ns | 0.0233 ns | 0.0239 ns | 0.0427 ns | - | - |
+/// | TestConversionToString | 17.8216 ns | 0.2321 ns | 0.1938 ns | 17.7613 ns | 0.0051 | 64 B |
diff --git a/benchmarks/Neo.Json.Benchmarks/Benchmark_JNumber.cs b/benchmarks/Neo.Json.Benchmarks/Benchmark_JNumber.cs
new file mode 100644
index 0000000000..abaaf00171
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Benchmark_JNumber.cs
@@ -0,0 +1,54 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmark_JNumber.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+
+namespace Neo.Json.Benchmarks;
+
+[MemoryDiagnoser]
+[CsvMeasurementsExporter]
+[MarkdownExporter]
+public class Benchmark_JNumber
+{
+ private JNumber _maxInt = new(JNumber.MAX_SAFE_INTEGER);
+ private JNumber _zero = new(0);
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _maxInt = new JNumber(JNumber.MAX_SAFE_INTEGER);
+ _zero = new JNumber(0);
+ }
+
+ [Benchmark]
+ public void TestAsBoolean()
+ {
+ _ = _maxInt.AsBoolean();
+ _ = _zero.AsBoolean();
+ }
+
+ [Benchmark]
+ public void TestAsString()
+ {
+ _ = _maxInt.AsString();
+ }
+}
+
+/// BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2605)
+/// 13th Gen Intel Core i9-13900H, 1 CPU, 20 logical and 14 physical cores
+/// .NET SDK 9.0.101
+/// [Host] : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2 [AttachedDebugger]
+/// DefaultJob: .NET 9.0.0(9.0.24.52809), X64 RyuJIT AVX2
+///
+/// | Method | Mean | Error | StdDev | Gen0 | Allocated |
+/// |-------------- |----------:|----------:|----------:|-------:|----------:|
+/// | TestAsBoolean | 2.510 ns | 0.0603 ns | 0.0564 ns | - | - |
+/// | TestAsString | 87.000 ns | 1.2230 ns | 1.1440 ns | 0.0044 | 56 B |
diff --git a/benchmarks/Neo.Json.Benchmarks/Benchmark_JObject.cs b/benchmarks/Neo.Json.Benchmarks/Benchmark_JObject.cs
new file mode 100644
index 0000000000..e31eda3d3c
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Benchmark_JObject.cs
@@ -0,0 +1,62 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmark_JObject.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+
+namespace Neo.Json.Benchmarks;
+
+[MemoryDiagnoser]
+[CsvMeasurementsExporter]
+[MarkdownExporter]
+public class Benchmark_JObject
+{
+ private JObject _alice = new();
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _alice = new JObject
+ {
+ ["name"] = "Alice",
+ ["age"] = 30
+ };
+ }
+
+ [Benchmark]
+ public void TestAddProperty()
+ {
+ _alice["city"] = "New York";
+ }
+
+ [Benchmark]
+ public void TestClone()
+ {
+ _ = _alice.Clone();
+ }
+
+ [Benchmark]
+ public static void TestParse()
+ {
+ JToken.Parse("{\"name\":\"John\", \"age\":25}");
+ }
+}
+
+/// BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2605)
+/// 13th Gen Intel Core i9-13900H, 1 CPU, 20 logical and 14 physical cores
+/// .NET SDK 9.0.101
+/// [Host] : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2 [AttachedDebugger]
+/// DefaultJob: .NET 9.0.0(9.0.24.52809), X64 RyuJIT AVX2
+///
+/// | Method | Mean | Error | StdDev | Gen0 | Allocated |
+/// |---------------- |----------:|---------:|---------:|-------:|----------:|
+/// | TestAddProperty | 11.35 ns | 0.135 ns | 0.119 ns | 0.0019 | 24 B |
+/// | TestClone | 123.72 ns | 1.898 ns | 1.585 ns | 0.0503 | 632 B |
+/// | TestParse | 240.81 ns | 2.974 ns | 2.322 ns | 0.0577 | 728 B |
diff --git a/benchmarks/Neo.Json.Benchmarks/Benchmark_JPath.cs b/benchmarks/Neo.Json.Benchmarks/Benchmark_JPath.cs
new file mode 100644
index 0000000000..04949d40e8
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Benchmark_JPath.cs
@@ -0,0 +1,54 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmark_JPath.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+
+namespace Neo.Json.Benchmarks;
+
+[MemoryDiagnoser]
+[CsvMeasurementsExporter]
+[MarkdownExporter]
+public class Benchmark_JPath
+{
+ private JObject _json = new();
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _json = new JObject
+ {
+ ["store"] = new JObject
+ {
+ ["book"] = new JArray
+ {
+ new JObject { ["title"] = "Book A", ["price"] = 10.99 },
+ new JObject { ["title"] = "Book B", ["price"] = 15.50 }
+ }
+ }
+ };
+ }
+
+ [Benchmark]
+ public void TestJsonPathQuery()
+ {
+ _json.JsonPath("$.store.book[*].title");
+ }
+}
+
+/// BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2605)
+/// 13th Gen Intel Core i9-13900H, 1 CPU, 20 logical and 14 physical cores
+/// .NET SDK 9.0.101
+/// [Host] : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2 [AttachedDebugger]
+/// DefaultJob : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2
+///
+/// | Method | Mean | Error | StdDev | Gen0 | Allocated |
+/// |------------------ |---------:|---------:|--------:|-------:|----------:|
+/// | TestJsonPathQuery | 679.7 ns | 11.84 ns | 9.89 ns | 0.1869 | 2.3 KB |
diff --git a/benchmarks/Neo.Json.Benchmarks/Benchmark_JString.cs b/benchmarks/Neo.Json.Benchmarks/Benchmark_JString.cs
new file mode 100644
index 0000000000..9133617170
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Benchmark_JString.cs
@@ -0,0 +1,58 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmark_JString.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+
+namespace Neo.Json.Benchmarks;
+
+[MemoryDiagnoser]
+[CsvMeasurementsExporter]
+[MarkdownExporter]
+public class Benchmark_JString
+{
+ private JString _testString = new(string.Empty);
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _testString = new JString("hello world");
+ }
+
+ [Benchmark]
+ public void TestLength()
+ {
+ _ = _testString.Value.Length;
+ }
+
+ [Benchmark]
+ public void TestConversionToString()
+ {
+ _ = _testString.ToString();
+ }
+
+ [Benchmark]
+ public void TestClone()
+ {
+ _ = _testString.Clone();
+ }
+}
+
+///BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2605)
+///13th Gen Intel Core i9-13900H, 1 CPU, 20 logical and 14 physical cores
+///.NET SDK 9.0.101
+/// [Host] : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2 [AttachedDebugger]
+/// DefaultJob : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2
+///
+///| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
+///|----------------------- |-----------:|----------:|----------:|-------:|-------:|----------:|
+///| TestLength | 0.0050 ns | 0.0044 ns | 0.0041 ns | - | - | - |
+///| TestConversionToString | 76.8631 ns | 1.0699 ns | 1.2737 ns | 0.0695 | 0.0001 | 872 B |
+///| TestClone | 0.0233 ns | 0.0104 ns | 0.0087 ns | - | - | - |
diff --git a/benchmarks/Neo.Json.Benchmarks/Benchmark_JsonArray.cs b/benchmarks/Neo.Json.Benchmarks/Benchmark_JsonArray.cs
new file mode 100644
index 0000000000..da09dc19d0
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Benchmark_JsonArray.cs
@@ -0,0 +1,217 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmark_JsonArray.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+
+namespace Neo.Json.Benchmarks;
+
+[MemoryDiagnoser] // 用于统计内存使用
+[CsvMeasurementsExporter] // CSV 格式导出
+[MarkdownExporter] // Markdown 格式导出
+public class Benchmark_JsonArray
+{
+ private JObject _alice = new();
+ private JObject _bob = new();
+ private JArray _jArray = new();
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _alice = new JObject
+ {
+ ["name"] = "alice",
+ ["age"] = 30,
+ ["score"] = 100.001,
+ ["gender"] = "female",
+ ["isMarried"] = true,
+ ["pet"] = new JObject
+ {
+ ["name"] = "Tom",
+ ["type"] = "cat"
+ }
+ };
+
+ _bob = new JObject
+ {
+ ["name"] = "bob",
+ ["age"] = 100000,
+ ["score"] = 0.001,
+ ["gender"] = "male",
+ ["isMarried"] = false,
+ ["pet"] = new JObject
+ {
+ ["name"] = "Paul",
+ ["type"] = "dog"
+ }
+ };
+
+ _jArray = new JArray();
+ }
+
+ [Benchmark]
+ public void TestAdd()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray.Add(_bob);
+ }
+
+ [Benchmark]
+ public void TestSetItem()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray[0] = _bob;
+ }
+
+ [Benchmark]
+ public void TestClear()
+ {
+ _jArray.Clear();
+ }
+
+ [Benchmark]
+ public void TestContains()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _ = _jArray.Contains(_alice);
+ }
+
+ [Benchmark]
+ public void TestCopyTo()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray.Add(_bob);
+
+ var objects = new JObject[2];
+ _jArray.CopyTo(objects, 0);
+ }
+
+ [Benchmark]
+ public void TestInsert()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray.Insert(0, _bob);
+ }
+
+ [Benchmark]
+ public void TestIndexOf()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _ = _jArray.IndexOf(_alice);
+ }
+
+ [Benchmark]
+ public void TestRemove()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray.Remove(_alice);
+ }
+
+ [Benchmark]
+ public void TestRemoveAt()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray.Add(_bob);
+ _jArray.RemoveAt(1);
+ }
+
+ [Benchmark]
+ public void TestGetEnumerator()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray.Add(_bob);
+ foreach (var _ in _jArray)
+ {
+ // Do nothing, just enumerate
+ }
+ }
+
+ [Benchmark]
+ public void TestCount()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray.Add(_bob);
+ _ = _jArray.Count;
+ }
+
+ [Benchmark]
+ public void TestClone()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _ = (JArray)_jArray.Clone();
+ }
+
+ [Benchmark]
+ public void TestAddNull()
+ {
+ _jArray.Clear();
+ _jArray.Add(null);
+ }
+
+ [Benchmark]
+ public void TestSetNull()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray[0] = null;
+ }
+
+ [Benchmark]
+ public void TestInsertNull()
+ {
+ _jArray.Clear();
+ _jArray.Add(_alice);
+ _jArray.Insert(0, null);
+ }
+
+ [Benchmark]
+ public void TestRemoveNull()
+ {
+ _jArray.Clear();
+ _jArray.Add(null);
+ _jArray.Remove(null);
+ }
+}
+
+/// BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2605)
+/// 13th Gen Intel Core i9-13900H, 1 CPU, 20 logical and 14 physical cores
+/// .NET SDK 9.0.101
+/// [Host] : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2 [AttachedDebugger]
+/// DefaultJob : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2
+///
+/// | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
+/// |------------------ |------------:|----------:|----------:|-------:|-------:|----------:|
+/// | TestAdd | 10.8580 ns | 0.1532 ns | 0.1433 ns | - | - | - |
+/// | TestSetItem | 10.8238 ns | 0.1747 ns | 0.1459 ns | - | - | - |
+/// | TestClear | 0.0663 ns | 0.0139 ns | 0.0116 ns | - | - | - |
+/// | TestContains | 9.3212 ns | 0.1277 ns | 0.1195 ns | - | - | - |
+/// | TestCopyTo | 18.6370 ns | 0.3341 ns | 0.2790 ns | 0.0032 | - | 40 B |
+/// | TestInsert | 12.3404 ns | 0.1256 ns | 0.1175 ns | - | - | - |
+/// | TestIndexOf | 9.2549 ns | 0.1196 ns | 0.1119 ns | - | - | - |
+/// | TestRemove | 8.6535 ns | 0.1912 ns | 0.2276 ns | - | - | - |
+/// | TestRemoveAt | 11.2368 ns | 0.0703 ns | 0.0549 ns | - | - | - |
+/// | TestGetEnumerator | 17.5149 ns | 0.1480 ns | 0.1384 ns | 0.0032 | - | 40 B |
+/// | TestCount | 9.4478 ns | 0.1740 ns | 0.1627 ns | - | - | - |
+/// | TestClone | 442.3215 ns | 6.7589 ns | 6.3223 ns | 0.1464 | 0.0005 | 1840 B |
+/// | TestAddNull | 2.1299 ns | 0.0309 ns | 0.0289 ns | - | - | - |
+/// | TestSetNull | 6.2627 ns | 0.0706 ns | 0.0661 ns | - | - | - |
+/// | TestInsertNull | 8.9616 ns | 0.0868 ns | 0.0812 ns | - | - | - |
+/// | TestRemoveNull | 5.2719 ns | 0.0489 ns | 0.0457 ns | - | - | - |
diff --git a/benchmarks/Neo.Json.Benchmarks/Benchmark_JsonDeserialize.cs b/benchmarks/Neo.Json.Benchmarks/Benchmark_JsonDeserialize.cs
new file mode 100644
index 0000000000..0c9ac61e6a
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Benchmark_JsonDeserialize.cs
@@ -0,0 +1,155 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Benchmark_JsonDeserialize.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Attributes;
+using Newtonsoft.Json;
+
+namespace Neo.Json.Benchmarks;
+
+[MemoryDiagnoser] // Enabling Memory Diagnostics
+[CsvMeasurementsExporter] // Export results in CSV format
+[MarkdownExporter] // Exporting results in Markdown format
+public class Benchmark_JsonDeserialize
+{
+ private string _jsonString = string.Empty;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ // Reading JSON files
+ _jsonString = File.ReadAllText("Data/RpcTestCases.json");
+ }
+
+ ///
+ /// Deserialization with Newtonsoft.Json
+ ///
+ [Benchmark]
+ public List? Newtonsoft_Deserialize()
+ {
+ return JsonConvert.DeserializeObject>(_jsonString);
+ }
+
+ ///
+ /// Deserialization with Neo.Json (supports nested parsing)
+ ///
+ [Benchmark]
+ public List NeoJson_Deserialize()
+ {
+ // Parses into JArray
+ if (JToken.Parse(_jsonString) is not JArray neoJsonObject)
+ return [];
+
+ var result = new List();
+
+ foreach (var item in neoJsonObject)
+ {
+ var testCase = new RpcTestCase
+ {
+ Name = item?["Name"]?.GetString(),
+ Request = new RpcRequest
+ {
+ JsonRpc = item?["Request"]?["jsonrpc"]?.GetString(),
+ Method = item?["Request"]?["method"]?.GetString(),
+ Params = ConvertToJTokenArray(item?["Request"]?["params"]),
+ Id = item?["Request"]?["id"]?.GetNumber()
+ },
+ Response = new RpcResponse
+ {
+ JsonRpc = item?["Response"]?["jsonrpc"]?.GetString(),
+ Id = item?["Response"]?["id"]?.GetNumber(),
+ Result = item?["Response"]?["result"]
+ }
+ };
+ result.Add(testCase);
+ }
+ return result;
+ }
+
+ ///
+ /// Recursively parsing params and stack arrays
+ ///
+ private static List ParseParams(JToken? token)
+ {
+ var result = new List();
+
+ if (token is JArray array)
+ {
+ // Parsing JArray correctly with foreach
+ foreach (var item in array)
+ {
+ result.Add(ParseParams(item));
+ }
+ }
+ else if (token is JObject obj)
+ {
+ // Properties traversal with Neo.Json.JObject
+ var dict = new Dictionary();
+ foreach (var property in obj.Properties)
+ {
+ dict[property.Key] = property.Value?.GetString();
+ }
+ result.Add(dict);
+ }
+ else
+ {
+ // If it's a normal value, it's straightforward to add
+ result.Add(token?.GetString());
+ }
+
+ return result;
+ }
+
+ ///
+ /// Parses any type of JSON into a JToken[] (for nested structures)
+ ///
+ private static JToken[] ConvertToJTokenArray(JToken? token)
+ {
+ var result = new List();
+
+ if (token is JArray array)
+ {
+ // If it's a JArray, parse it one by one and add it to the result
+ foreach (var item in array)
+ {
+ result.AddRange(ConvertToJTokenArray(item));
+ }
+ }
+ else if (token is JObject obj)
+ {
+ // Convert JObject to JToken (Dictionary type)
+ var newObj = new JObject();
+ foreach (var property in obj.Properties)
+ newObj[property.Key] = property.Value as JString;
+ result.Add(newObj);
+ }
+ else
+ {
+ // Add the base type JToken directly
+ result.Add(token);
+ }
+
+ return [.. result!]; // Converting a List to an Array of JTokens
+ }
+}
+
+// This is benchmark after bug fix.
+
+// BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2894)
+// Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
+// .NET SDK 9.0.102
+// [Host] : .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2
+// DefaultJob: .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2
+
+
+// | Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
+// | ----------------------- |-----------:| ---------:| ---------:| ---------:| ---------:| --------:| ----------:|
+// | Newtonsoft_Deserialize | 1,066.7 us | 19.89 us | 34.84 us | 158.2031 | 115.2344 | - | 978.52 KB |
+// | NeoJson_Deserialize | 777.9 us | 11.27 us | 9.41 us | 144.5313 | 70.3125 | 35.1563 | 919.27 KB |
diff --git a/benchmarks/Neo.Json.Benchmarks/Data/RpcTestCases.json b/benchmarks/Neo.Json.Benchmarks/Data/RpcTestCases.json
new file mode 100644
index 0000000000..bcc82c91d9
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Data/RpcTestCases.json
@@ -0,0 +1,4034 @@
+[
+ {
+ "Name": "sendrawtransactionasyncerror",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "sendrawtransaction",
+ "params": [ "ANIHn05ujtUAAAAAACYcEwAAAAAAQkEAAAEKo4e1Ppa3mJpjFDGgVt0fQKBC9gEAXQMAyBeoBAAAAAwUzViuz9M1vh6z0xHh3IAJY9/XLZ8MFAqjh7U+lreYmmMUMaBW3R9AoEL2E8AMCHRyYW5zZmVyDBSlB7dGdv/td+dUuG7NmQnwus08ukFifVtSOAFCDEDh8zgTrGUXyzVX60wBCMyajNRfzFRiEPAe8CgGQ10bA2C3fnVz68Gw+Amgn5gmvuNfYKgWQ/W68Km1bYUPlnEYKQwhA86j4vgfGvk1ItKe3k8kofC+3q1ykzkdM4gPVHXZeHjJC0GVRA14" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "error": {
+ "code": -500,
+ "message": "InsufficientFunds",
+ "data": " at Neo.Plugins.RpcServer.GetRelayResult(RelayResultReason reason, UInt256 hash)\r\n at Neo.Network.RPC.Models.RpcServer.SendRawTransaction(JArray _params)\r\n at Neo.Network.RPC.Models.RpcServer.ProcessRequest(HttpContext context, JObject request)"
+ }
+ }
+ },
+ {
+ "Name": "getbestblockhashasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getbestblockhash",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "0x530de76326a8662d1b730ba4fbdf011051eabd142015587e846da42376adf35f"
+ }
+ },
+ {
+ "Name": "getblockhexasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblock",
+ "params": [ 0 ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "0000000000000000000000000000000000000000000000000000000000000000000000002bbb6298fc7039330cdfd2e4dfbe976ee72c4cba6c16d68f0b49ab1bca685b7388ea19ef55010000000000009903b0c3d292988febe5f306a02f654ea2eb16290100011102001dac2b7c000000000000000000ca61e52e881d41374e640f819cd118cc153b21a7000000000000000000000000000000000000000000000541123e7fe801000111"
+ }
+ },
+ {
+ "Name": "getblockhexasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblock",
+ "params": [ "0xe191fe1aea732c3e23f20af8a95e09f95891176f8064a2fce8571d51f80619a8" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "0000000000000000000000000000000000000000000000000000000000000000000000002bbb6298fc7039330cdfd2e4dfbe976ee72c4cba6c16d68f0b49ab1bca685b7388ea19ef55010000000000009903b0c3d292988febe5f306a02f654ea2eb16290100011102001dac2b7c000000000000000000ca61e52e881d41374e640f819cd118cc153b21a7000000000000000000000000000000000000000000000541123e7fe801000111"
+ }
+ },
+ {
+ "Name": "getblockasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblock",
+ "params": [ 7, true ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0x6d1556889c92249da88d2fb7729ae82fb2cc1b45dcd9030a40208b72a1d3cb83",
+ "size": 470,
+ "version": 0,
+ "previousblockhash": "0xaae8867e9086afaf06fd02cc538e88a69b801abd6f9d3ae39ae630e29d5b39e2",
+ "merkleroot": "0xe95761f21c733ad53066786af24ee5d613b32bd5aae538df2d611492ec0cae82",
+ "time": 1594867377561,
+ "nonce": "FFFFFFFFFFFFFFFF",
+ "index": 7,
+ "primary": 1,
+ "nextconsensus": "NikvsLcNP1jWhrFPrfS3n4spEASgdNYTG2",
+ "witnesses": [
+ {
+ "invocation": "DEBs6hZDHUtL7KOJuF1m8/vITM8VeduwegKhBdbqcLKdBzXA1uZZiBl8jM/rhjXBaIGQSFIQuq8Er1Nb5y5/DWUx",
+ "verification": "EQwhAqnqaELMDLOw8jF7B8hQ3j0eKyQ6mO0tVqP/TKZqrzMLEQtBE43vrw=="
+ }
+ ],
+ "tx": [
+ {
+ "hash": "0x83d44d71d59f854bc29f4e3932bf68703545807d05fb5429504d70cfc8d05071",
+ "size": 248,
+ "version": 0,
+ "nonce": 631973574,
+ "sender": "NikvsLcNP1jWhrFPrfS3n4spEASgdNYTG2",
+ "sysfee": "9007990",
+ "netfee": "1248450",
+ "validuntilblock": 2102405,
+ "signers": [
+ {
+ "account": "0xe19de267a37a71734478f512b3e92c79fc3695fa",
+ "scopes": "CalledByEntry"
+ }
+ ],
+ "attributes": [],
+ "script": "AccyDBQcA1dGS3d\u002Bz2tfOsOJOs4fixYh9gwU\u002BpU2/Hks6bMS9XhEc3F6o2fineETwAwIdHJhbnNmZXIMFCUFnstIeNOodfkcUc7e0zDUV1/eQWJ9W1I4",
+ "witnesses": [
+ {
+ "invocation": "DEDZxkskUb1aH1I4EX5ja02xrYX4fCubAmQzBuPpfY7pDEb1n4Dzx\u002BUB\u002BqSdC/CGskGf5BuzJ0MWJJipsHuivKmU",
+ "verification": "EQwhAqnqaELMDLOw8jF7B8hQ3j0eKyQ6mO0tVqP/TKZqrzMLEQtBE43vrw=="
+ }
+ ]
+ }
+ ],
+ "confirmations": 695,
+ "nextblockhash": "0xc4b986813396932a47d6823a9987ccee0148c6fca0150102f4b24ce05cfc9c6f"
+ }
+ }
+ },
+ {
+ "Name": "getblockasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblock",
+ "params": [ "0xb9579b028e4cf31a0c3bd9582f9f7fbd40b0e0495604406b8f530c7ebce5bcc8", true ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0x6d1556889c92249da88d2fb7729ae82fb2cc1b45dcd9030a40208b72a1d3cb83",
+ "size": 470,
+ "version": 0,
+ "previousblockhash": "0xaae8867e9086afaf06fd02cc538e88a69b801abd6f9d3ae39ae630e29d5b39e2",
+ "merkleroot": "0xe95761f21c733ad53066786af24ee5d613b32bd5aae538df2d611492ec0cae82",
+ "time": 1594867377561,
+ "nonce": "FFFFFFFFFFFFFFFF",
+ "index": 7,
+ "primary": 1,
+ "nextconsensus": "NikvsLcNP1jWhrFPrfS3n4spEASgdNYTG2",
+ "witnesses": [
+ {
+ "invocation": "DEBs6hZDHUtL7KOJuF1m8/vITM8VeduwegKhBdbqcLKdBzXA1uZZiBl8jM/rhjXBaIGQSFIQuq8Er1Nb5y5/DWUx",
+ "verification": "EQwhAqnqaELMDLOw8jF7B8hQ3j0eKyQ6mO0tVqP/TKZqrzMLEQtBE43vrw=="
+ }
+ ],
+ "tx": [
+ {
+ "hash": "0x83d44d71d59f854bc29f4e3932bf68703545807d05fb5429504d70cfc8d05071",
+ "size": 248,
+ "version": 0,
+ "nonce": 631973574,
+ "sender": "NikvsLcNP1jWhrFPrfS3n4spEASgdNYTG2",
+ "sysfee": "9007990",
+ "netfee": "1248450",
+ "validuntilblock": 2102405,
+ "signers": [
+ {
+ "account": "0xe19de267a37a71734478f512b3e92c79fc3695fa",
+ "scopes": "CalledByEntry"
+ }
+ ],
+ "attributes": [],
+ "script": "AccyDBQcA1dGS3d\u002Bz2tfOsOJOs4fixYh9gwU\u002BpU2/Hks6bMS9XhEc3F6o2fineETwAwIdHJhbnNmZXIMFCUFnstIeNOodfkcUc7e0zDUV1/eQWJ9W1I4",
+ "witnesses": [
+ {
+ "invocation": "DEDZxkskUb1aH1I4EX5ja02xrYX4fCubAmQzBuPpfY7pDEb1n4Dzx\u002BUB\u002BqSdC/CGskGf5BuzJ0MWJJipsHuivKmU",
+ "verification": "EQwhAqnqaELMDLOw8jF7B8hQ3j0eKyQ6mO0tVqP/TKZqrzMLEQtBE43vrw=="
+ }
+ ]
+ }
+ ],
+ "confirmations": 695,
+ "nextblockhash": "0xc4b986813396932a47d6823a9987ccee0148c6fca0150102f4b24ce05cfc9c6f"
+ }
+ }
+ },
+ {
+ "Name": "getblockheadercountasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblockheadercount",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": 3825
+ }
+ },
+ {
+ "Name": "getblockcountasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblockcount",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": 2691
+ }
+ },
+ {
+ "Name": "getblockhashasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblockhash",
+ "params": [ 0 ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "0xe191fe1aea732c3e23f20af8a95e09f95891176f8064a2fce8571d51f80619a8"
+ }
+ },
+ {
+ "Name": "getblockheaderhexasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblockheader",
+ "params": [ 0 ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "0000000000000000000000000000000000000000000000000000000000000000000000002bbb6298fc7039330cdfd2e4dfbe976ee72c4cba6c16d68f0b49ab1bca685b7388ea19ef55010000000000009903b0c3d292988febe5f306a02f654ea2eb16290100011100"
+ }
+ },
+ {
+ "Name": "getblockheaderhexasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblockheader",
+ "params": [ "0xe191fe1aea732c3e23f20af8a95e09f95891176f8064a2fce8571d51f80619a8" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "0000000000000000000000000000000000000000000000000000000000000000000000002bbb6298fc7039330cdfd2e4dfbe976ee72c4cba6c16d68f0b49ab1bca685b7388ea19ef55010000000000009903b0c3d292988febe5f306a02f654ea2eb16290100011100"
+ }
+ },
+ {
+ "Name": "getblockheaderasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblockheader",
+ "params": [ 0, true ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0xbbf7e191d4947f8a4dc33477902dacd0b047e371a81c18a6df62fe0d541725f5",
+ "size": 113,
+ "version": 0,
+ "previousblockhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "merkleroot": "0x735b68ca1bab490b8fd6166cba4c2ce76e97bedfe4d2df0c333970fc9862bb2b",
+ "time": 1468595301000,
+ "nonce": "FFFFFFFFFFFFFFFF",
+ "index": 0,
+ "primary": 1,
+ "nextconsensus": "NZs2zXSPuuv9ZF6TDGSWT1RBmE8rfGj7UW",
+ "witnesses": [
+ {
+ "invocation": "",
+ "verification": "EQ=="
+ }
+ ],
+ "confirmations": 2700,
+ "nextblockhash": "0x423173109798b038019b35129417b55cc4b5976ac79978dfab8ea2512d155f69"
+ }
+ }
+ },
+ {
+ "Name": "getblockheaderasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblockheader",
+ "params": [ "0x656bcb02e4fe8a19dbb15149073a5ae0bd8adc2da8504b67b112b44f68b4c9d7", true ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0xbbf7e191d4947f8a4dc33477902dacd0b047e371a81c18a6df62fe0d541725f5",
+ "size": 113,
+ "version": 0,
+ "previousblockhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "merkleroot": "0x735b68ca1bab490b8fd6166cba4c2ce76e97bedfe4d2df0c333970fc9862bb2b",
+ "time": 1468595301000,
+ "nonce": "FFFFFFFFFFFFFFFF",
+ "index": 0,
+ "primary": 1,
+ "nextconsensus": "NZs2zXSPuuv9ZF6TDGSWT1RBmE8rfGj7UW",
+ "witnesses": [
+ {
+ "invocation": "",
+ "verification": "EQ=="
+ }
+ ],
+ "confirmations": 2700,
+ "nextblockhash": "0x423173109798b038019b35129417b55cc4b5976ac79978dfab8ea2512d155f69"
+ }
+ }
+ },
+ {
+ "Name": "getblocksysfeeasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getblocksysfee",
+ "params": [ 100 ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "300000000"
+ }
+ },
+ {
+ "Name": "getcommitteeasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getcommittee",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": [
+ "02ced432397ddc44edba031c0bc3b933f28fdd9677792d7b20e6c036ddaaacf1e2"
+ ]
+ }
+ },
+ {
+ "Name": "getcontractstateasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getcontractstate",
+ "params": [ "gastoken" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "id": -6,
+ "updatecounter": 0,
+ "hash": "0xd2a4cff31913016155e38e474a2c06d08be276cf",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=",
+ "checksum": 2663858513
+ },
+ "manifest": {
+ "name": "GasToken",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [
+ "NEP-17"
+ ],
+ "abi": {
+ "methods": [
+ {
+ "name": "balanceOf",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "decimals",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 7,
+ "safe": true
+ },
+ {
+ "name": "symbol",
+ "parameters": [],
+ "returntype": "String",
+ "offset": 14,
+ "safe": true
+ },
+ {
+ "name": "totalSupply",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 21,
+ "safe": true
+ },
+ {
+ "name": "transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 28,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ }
+ }
+ },
+ {
+ "Name": "getcontractstateasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getcontractstate",
+ "params": [ -6 ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "id": -6,
+ "updatecounter": 0,
+ "hash": "0xd2a4cff31913016155e38e474a2c06d08be276cf",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=",
+ "checksum": 2663858513
+ },
+ "manifest": {
+ "name": "GasToken",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [
+ "NEP-17"
+ ],
+ "abi": {
+ "methods": [
+ {
+ "name": "balanceOf",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "decimals",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 7,
+ "safe": true
+ },
+ {
+ "name": "symbol",
+ "parameters": [],
+ "returntype": "String",
+ "offset": 14,
+ "safe": true
+ },
+ {
+ "name": "totalSupply",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 21,
+ "safe": true
+ },
+ {
+ "name": "transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 28,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ }
+ }
+ },
+ {
+ "Name": "getcontractstateasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getcontractstate",
+ "params": [ "0xd2a4cff31913016155e38e474a2c06d08be276cf" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "id": -6,
+ "updatecounter": 0,
+ "hash": "0xd2a4cff31913016155e38e474a2c06d08be276cf",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=",
+ "checksum": 2663858513
+ },
+ "manifest": {
+ "name": "GasToken",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [
+ "NEP-17"
+ ],
+ "abi": {
+ "methods": [
+ {
+ "name": "balanceOf",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "decimals",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 7,
+ "safe": true
+ },
+ {
+ "name": "symbol",
+ "parameters": [],
+ "returntype": "String",
+ "offset": 14,
+ "safe": true
+ },
+ {
+ "name": "totalSupply",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 21,
+ "safe": true
+ },
+ {
+ "name": "transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 28,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ }
+ }
+ },
+ {
+ "Name": "getcontractstateasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "getcontractstate",
+ "params": [ "neotoken" ]
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "id": -5,
+ "updatecounter": 1,
+ "hash": "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=",
+ "checksum": 1325686241
+ },
+ "manifest": {
+ "name": "NeoToken",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [
+ "NEP-17"
+ ],
+ "abi": {
+ "methods": [
+ {
+ "name": "balanceOf",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "decimals",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 7,
+ "safe": true
+ },
+ {
+ "name": "getAccountState",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 14,
+ "safe": true
+ },
+ {
+ "name": "getAllCandidates",
+ "parameters": [],
+ "returntype": "InteropInterface",
+ "offset": 21,
+ "safe": true
+ },
+ {
+ "name": "getCandidateVote",
+ "parameters": [
+ {
+ "name": "pubKey",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 28,
+ "safe": true
+ },
+ {
+ "name": "getCandidates",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 35,
+ "safe": true
+ },
+ {
+ "name": "getCommittee",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 42,
+ "safe": true
+ },
+ {
+ "name": "getCommitteeAddress",
+ "parameters": [],
+ "returntype": "Hash160",
+ "offset": 49,
+ "safe": true
+ },
+ {
+ "name": "getGasPerBlock",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 56,
+ "safe": true
+ },
+ {
+ "name": "getNextBlockValidators",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 63,
+ "safe": true
+ },
+ {
+ "name": "getRegisterPrice",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 70,
+ "safe": true
+ },
+ {
+ "name": "registerCandidate",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 77,
+ "safe": false
+ },
+ {
+ "name": "setGasPerBlock",
+ "parameters": [
+ {
+ "name": "gasPerBlock",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 84,
+ "safe": false
+ },
+ {
+ "name": "setRegisterPrice",
+ "parameters": [
+ {
+ "name": "registerPrice",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 91,
+ "safe": false
+ },
+ {
+ "name": "symbol",
+ "parameters": [],
+ "returntype": "String",
+ "offset": 98,
+ "safe": true
+ },
+ {
+ "name": "totalSupply",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 105,
+ "safe": true
+ },
+ {
+ "name": "transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 112,
+ "safe": false
+ },
+ {
+ "name": "unclaimedGas",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "end",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 119,
+ "safe": true
+ },
+ {
+ "name": "unregisterCandidate",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 126,
+ "safe": false
+ },
+ {
+ "name": "vote",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "voteTo",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 133,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ },
+ {
+ "name": "CandidateStateChanged",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "PublicKey"
+ },
+ {
+ "name": "registered",
+ "type": "Boolean"
+ },
+ {
+ "name": "votes",
+ "type": "Integer"
+ }
+ ]
+ },
+ {
+ "name": "Vote",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "from",
+ "type": "PublicKey"
+ },
+ {
+ "name": "to",
+ "type": "PublicKey"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ },
+ {
+ "name": "CommitteeChanged",
+ "parameters": [
+ {
+ "name": "old",
+ "type": "Array"
+ },
+ {
+ "name": "new",
+ "type": "Array"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ }
+ }
+ },
+ {
+ "Name": "getcontractstateasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "getcontractstate",
+ "params": [ -5 ]
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "id": -5,
+ "updatecounter": 1,
+ "hash": "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=",
+ "checksum": 1325686241
+ },
+ "manifest": {
+ "name": "NeoToken",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [
+ "NEP-17"
+ ],
+ "abi": {
+ "methods": [
+ {
+ "name": "balanceOf",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "decimals",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 7,
+ "safe": true
+ },
+ {
+ "name": "getAccountState",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 14,
+ "safe": true
+ },
+ {
+ "name": "getAllCandidates",
+ "parameters": [],
+ "returntype": "InteropInterface",
+ "offset": 21,
+ "safe": true
+ },
+ {
+ "name": "getCandidateVote",
+ "parameters": [
+ {
+ "name": "pubKey",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 28,
+ "safe": true
+ },
+ {
+ "name": "getCandidates",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 35,
+ "safe": true
+ },
+ {
+ "name": "getCommittee",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 42,
+ "safe": true
+ },
+ {
+ "name": "getCommitteeAddress",
+ "parameters": [],
+ "returntype": "Hash160",
+ "offset": 49,
+ "safe": true
+ },
+ {
+ "name": "getGasPerBlock",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 56,
+ "safe": true
+ },
+ {
+ "name": "getNextBlockValidators",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 63,
+ "safe": true
+ },
+ {
+ "name": "getRegisterPrice",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 70,
+ "safe": true
+ },
+ {
+ "name": "registerCandidate",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 77,
+ "safe": false
+ },
+ {
+ "name": "setGasPerBlock",
+ "parameters": [
+ {
+ "name": "gasPerBlock",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 84,
+ "safe": false
+ },
+ {
+ "name": "setRegisterPrice",
+ "parameters": [
+ {
+ "name": "registerPrice",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 91,
+ "safe": false
+ },
+ {
+ "name": "symbol",
+ "parameters": [],
+ "returntype": "String",
+ "offset": 98,
+ "safe": true
+ },
+ {
+ "name": "totalSupply",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 105,
+ "safe": true
+ },
+ {
+ "name": "transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 112,
+ "safe": false
+ },
+ {
+ "name": "unclaimedGas",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "end",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 119,
+ "safe": true
+ },
+ {
+ "name": "unregisterCandidate",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 126,
+ "safe": false
+ },
+ {
+ "name": "vote",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "voteTo",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 133,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ },
+ {
+ "name": "CandidateStateChanged",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "PublicKey"
+ },
+ {
+ "name": "registered",
+ "type": "Boolean"
+ },
+ {
+ "name": "votes",
+ "type": "Integer"
+ }
+ ]
+ },
+ {
+ "name": "Vote",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "from",
+ "type": "PublicKey"
+ },
+ {
+ "name": "to",
+ "type": "PublicKey"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ },
+ {
+ "name": "CommitteeChanged",
+ "parameters": [
+ {
+ "name": "old",
+ "type": "Array"
+ },
+ {
+ "name": "new",
+ "type": "Array"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ }
+ }
+ },
+ {
+ "Name": "getcontractstateasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "getcontractstate",
+ "params": [ "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5" ]
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "id": -5,
+ "updatecounter": 1,
+ "hash": "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "EEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0AQQRr3e2dAEEEa93tnQBBBGvd7Z0A=",
+ "checksum": 1325686241
+ },
+ "manifest": {
+ "name": "NeoToken",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [
+ "NEP-17"
+ ],
+ "abi": {
+ "methods": [
+ {
+ "name": "balanceOf",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "decimals",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 7,
+ "safe": true
+ },
+ {
+ "name": "getAccountState",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 14,
+ "safe": true
+ },
+ {
+ "name": "getAllCandidates",
+ "parameters": [],
+ "returntype": "InteropInterface",
+ "offset": 21,
+ "safe": true
+ },
+ {
+ "name": "getCandidateVote",
+ "parameters": [
+ {
+ "name": "pubKey",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 28,
+ "safe": true
+ },
+ {
+ "name": "getCandidates",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 35,
+ "safe": true
+ },
+ {
+ "name": "getCommittee",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 42,
+ "safe": true
+ },
+ {
+ "name": "getCommitteeAddress",
+ "parameters": [],
+ "returntype": "Hash160",
+ "offset": 49,
+ "safe": true
+ },
+ {
+ "name": "getGasPerBlock",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 56,
+ "safe": true
+ },
+ {
+ "name": "getNextBlockValidators",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 63,
+ "safe": true
+ },
+ {
+ "name": "getRegisterPrice",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 70,
+ "safe": true
+ },
+ {
+ "name": "registerCandidate",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 77,
+ "safe": false
+ },
+ {
+ "name": "setGasPerBlock",
+ "parameters": [
+ {
+ "name": "gasPerBlock",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 84,
+ "safe": false
+ },
+ {
+ "name": "setRegisterPrice",
+ "parameters": [
+ {
+ "name": "registerPrice",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 91,
+ "safe": false
+ },
+ {
+ "name": "symbol",
+ "parameters": [],
+ "returntype": "String",
+ "offset": 98,
+ "safe": true
+ },
+ {
+ "name": "totalSupply",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 105,
+ "safe": true
+ },
+ {
+ "name": "transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 112,
+ "safe": false
+ },
+ {
+ "name": "unclaimedGas",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "end",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 119,
+ "safe": true
+ },
+ {
+ "name": "unregisterCandidate",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 126,
+ "safe": false
+ },
+ {
+ "name": "vote",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "voteTo",
+ "type": "PublicKey"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 133,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ },
+ {
+ "name": "CandidateStateChanged",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "PublicKey"
+ },
+ {
+ "name": "registered",
+ "type": "Boolean"
+ },
+ {
+ "name": "votes",
+ "type": "Integer"
+ }
+ ]
+ },
+ {
+ "name": "Vote",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "from",
+ "type": "PublicKey"
+ },
+ {
+ "name": "to",
+ "type": "PublicKey"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ },
+ {
+ "name": "CommitteeChanged",
+ "parameters": [
+ {
+ "name": "old",
+ "type": "Array"
+ },
+ {
+ "name": "new",
+ "type": "Array"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ }
+ }
+ },
+ {
+ "Name": "getnativecontractsasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "getnativecontracts",
+ "params": []
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": [
+ {
+ "id": -1,
+ "updatecounter": 0,
+ "hash": "0xa501d7d7d10983673b61b7a2d3a813b36f9f0e43",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "D0Ea93tn",
+ "checksum": 3516775561
+ },
+ "manifest": {
+ "name": "ContractManagement",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [],
+ "abi": {
+ "methods": [
+ {
+ "name": "deploy",
+ "parameters": [
+ {
+ "name": "nefFile",
+ "type": "ByteArray"
+ },
+ {
+ "name": "manifest",
+ "type": "ByteArray"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "deploy",
+ "parameters": [
+ {
+ "name": "nefFile",
+ "type": "ByteArray"
+ },
+ {
+ "name": "manifest",
+ "type": "ByteArray"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "destroy",
+ "parameters": [],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "getContract",
+ "parameters": [
+ {
+ "name": "hash",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getMinimumDeploymentFee",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "setMinimumDeploymentFee",
+ "parameters": [
+ {
+ "name": "value",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "update",
+ "parameters": [
+ {
+ "name": "nefFile",
+ "type": "ByteArray"
+ },
+ {
+ "name": "manifest",
+ "type": "ByteArray"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "update",
+ "parameters": [
+ {
+ "name": "nefFile",
+ "type": "ByteArray"
+ },
+ {
+ "name": "manifest",
+ "type": "ByteArray"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Deploy",
+ "parameters": [
+ {
+ "name": "Hash",
+ "type": "Hash160"
+ }
+ ]
+ },
+ {
+ "name": "Update",
+ "parameters": [
+ {
+ "name": "Hash",
+ "type": "Hash160"
+ }
+ ]
+ },
+ {
+ "name": "Destroy",
+ "parameters": [
+ {
+ "name": "Hash",
+ "type": "Hash160"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ },
+ {
+ "id": -2,
+ "updatecounter": 1,
+ "hash": "0x971d69c6dd10ce88e7dfffec1dc603c6125a8764",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "AP5BGvd7Zw==",
+ "checksum": 3395482975
+ },
+ "manifest": {
+ "name": "LedgerContract",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [],
+ "abi": {
+ "methods": [
+ {
+ "name": "currentHash",
+ "parameters": [],
+ "returntype": "Hash256",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "currentIndex",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getBlock",
+ "parameters": [
+ {
+ "name": "indexOrHash",
+ "type": "ByteArray"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getTransaction",
+ "parameters": [
+ {
+ "name": "hash",
+ "type": "Hash256"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getTransactionFromBlock",
+ "parameters": [
+ {
+ "name": "blockIndexOrHash",
+ "type": "ByteArray"
+ },
+ {
+ "name": "txIndex",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getTransactionHeight",
+ "parameters": [
+ {
+ "name": "hash",
+ "type": "Hash256"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ }
+ ],
+ "events": []
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ },
+ {
+ "id": -3,
+ "updatecounter": 0,
+ "hash": "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "AP1BGvd7Zw==",
+ "checksum": 3921333105
+ },
+ "manifest": {
+ "name": "NeoToken",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [
+ "NEP-17"
+ ],
+ "abi": {
+ "methods": [
+ {
+ "name": "balanceOf",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "decimals",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getCandidates",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getCommittee",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getGasPerBlock",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getNextBlockValidators",
+ "parameters": [],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "registerCandidate",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "ByteArray"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "setGasPerBlock",
+ "parameters": [
+ {
+ "name": "gasPerBlock",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "symbol",
+ "parameters": [],
+ "returntype": "String",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "totalSupply",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "unclaimedGas",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "end",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "unregisterCandidate",
+ "parameters": [
+ {
+ "name": "pubkey",
+ "type": "ByteArray"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "vote",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ },
+ {
+ "name": "voteTo",
+ "type": "ByteArray"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ },
+ {
+ "id": -4,
+ "updatecounter": 0,
+ "hash": "0xd2a4cff31913016155e38e474a2c06d08be276cf",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "APxBGvd7Zw==",
+ "checksum": 3155977747
+ },
+ "manifest": {
+ "name": "GasToken",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [
+ "NEP-17"
+ ],
+ "abi": {
+ "methods": [
+ {
+ "name": "balanceOf",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "decimals",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "symbol",
+ "parameters": [],
+ "returntype": "String",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "totalSupply",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ },
+ {
+ "name": "data",
+ "type": "Any"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ },
+ {
+ "id": -5,
+ "updatecounter": 0,
+ "hash": "0x79bcd398505eb779df6e67e4be6c14cded08e2f2",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "APtBGvd7Zw==",
+ "checksum": 1136340263
+ },
+ "manifest": {
+ "name": "PolicyContract",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [],
+ "abi": {
+ "methods": [
+ {
+ "name": "blockAccount",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "getExecFeeFactor",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getFeePerByte",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getMaxBlockSize",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getMaxBlockSystemFee",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getMaxTransactionsPerBlock",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getStoragePrice",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "isBlocked",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "setExecFeeFactor",
+ "parameters": [
+ {
+ "name": "value",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "setFeePerByte",
+ "parameters": [
+ {
+ "name": "value",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "setMaxBlockSize",
+ "parameters": [
+ {
+ "name": "value",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "setMaxBlockSystemFee",
+ "parameters": [
+ {
+ "name": "value",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "setMaxTransactionsPerBlock",
+ "parameters": [
+ {
+ "name": "value",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "setStoragePrice",
+ "parameters": [
+ {
+ "name": "value",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "unblockAccount",
+ "parameters": [
+ {
+ "name": "account",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ }
+ ],
+ "events": []
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ },
+ {
+ "id": -6,
+ "updatecounter": 0,
+ "hash": "0x597b1471bbce497b7809e2c8f10db67050008b02",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "APpBGvd7Zw==",
+ "checksum": 3289425910
+ },
+ "manifest": {
+ "name": "RoleManagement",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [],
+ "abi": {
+ "methods": [
+ {
+ "name": "designateAsRole",
+ "parameters": [
+ {
+ "name": "role",
+ "type": "Integer"
+ },
+ {
+ "name": "nodes",
+ "type": "Array"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "getDesignatedByRole",
+ "parameters": [
+ {
+ "name": "role",
+ "type": "Integer"
+ },
+ {
+ "name": "index",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Array",
+ "offset": 0,
+ "safe": true
+ }
+ ],
+ "events": []
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ },
+ {
+ "id": -7,
+ "updatecounter": 0,
+ "hash": "0x8dc0e742cbdfdeda51ff8a8b78d46829144c80ee",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "APlBGvd7Zw==",
+ "checksum": 3902663397
+ },
+ "manifest": {
+ "name": "OracleContract",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [],
+ "abi": {
+ "methods": [
+ {
+ "name": "finish",
+ "parameters": [],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "request",
+ "parameters": [
+ {
+ "name": "url",
+ "type": "String"
+ },
+ {
+ "name": "filter",
+ "type": "String"
+ },
+ {
+ "name": "callback",
+ "type": "String"
+ },
+ {
+ "name": "userData",
+ "type": "Any"
+ },
+ {
+ "name": "gasForResponse",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "verify",
+ "parameters": [],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": true
+ }
+ ],
+ "events": [
+ {
+ "name": "OracleRequest",
+ "parameters": [
+ {
+ "name": "Id",
+ "type": "Integer"
+ },
+ {
+ "name": "RequestContract",
+ "type": "Hash160"
+ },
+ {
+ "name": "Url",
+ "type": "String"
+ },
+ {
+ "name": "Filter",
+ "type": "String"
+ }
+ ]
+ },
+ {
+ "name": "OracleResponse",
+ "parameters": [
+ {
+ "name": "Id",
+ "type": "Integer"
+ },
+ {
+ "name": "OriginalTx",
+ "type": "Hash256"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ },
+ {
+ "id": -8,
+ "updatecounter": 0,
+ "hash": "0xa2b524b68dfe43a9d56af84f443c6b9843b8028c",
+ "nef": {
+ "magic": 860243278,
+ "compiler": "neo-core-v3.0",
+ "source": "",
+ "tokens": [],
+ "script": "APhBGvd7Zw==",
+ "checksum": 3740064217
+ },
+ "manifest": {
+ "name": "NameService",
+ "groups": [],
+ "features": {},
+ "supportedstandards": [],
+ "abi": {
+ "methods": [
+ {
+ "name": "addRoot",
+ "parameters": [
+ {
+ "name": "root",
+ "type": "String"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "balanceOf",
+ "parameters": [
+ {
+ "name": "owner",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "decimals",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "deleteRecord",
+ "parameters": [
+ {
+ "name": "name",
+ "type": "String"
+ },
+ {
+ "name": "type",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "getPrice",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "getRecord",
+ "parameters": [
+ {
+ "name": "name",
+ "type": "String"
+ },
+ {
+ "name": "type",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "String",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "isAvailable",
+ "parameters": [
+ {
+ "name": "name",
+ "type": "String"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "ownerOf",
+ "parameters": [
+ {
+ "name": "tokenId",
+ "type": "ByteArray"
+ }
+ ],
+ "returntype": "Hash160",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "properties",
+ "parameters": [
+ {
+ "name": "tokenId",
+ "type": "ByteArray"
+ }
+ ],
+ "returntype": "Map",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "register",
+ "parameters": [
+ {
+ "name": "name",
+ "type": "String"
+ },
+ {
+ "name": "owner",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "renew",
+ "parameters": [
+ {
+ "name": "name",
+ "type": "String"
+ }
+ ],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "resolve",
+ "parameters": [
+ {
+ "name": "name",
+ "type": "String"
+ },
+ {
+ "name": "type",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "String",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "setAdmin",
+ "parameters": [
+ {
+ "name": "name",
+ "type": "String"
+ },
+ {
+ "name": "admin",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "setPrice",
+ "parameters": [
+ {
+ "name": "price",
+ "type": "Integer"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "setRecord",
+ "parameters": [
+ {
+ "name": "name",
+ "type": "String"
+ },
+ {
+ "name": "type",
+ "type": "Integer"
+ },
+ {
+ "name": "data",
+ "type": "String"
+ }
+ ],
+ "returntype": "Void",
+ "offset": 0,
+ "safe": false
+ },
+ {
+ "name": "symbol",
+ "parameters": [],
+ "returntype": "String",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "tokensOf",
+ "parameters": [
+ {
+ "name": "owner",
+ "type": "Hash160"
+ }
+ ],
+ "returntype": "Any",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "totalSupply",
+ "parameters": [],
+ "returntype": "Integer",
+ "offset": 0,
+ "safe": true
+ },
+ {
+ "name": "transfer",
+ "parameters": [
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "tokenId",
+ "type": "ByteArray"
+ }
+ ],
+ "returntype": "Boolean",
+ "offset": 0,
+ "safe": false
+ }
+ ],
+ "events": [
+ {
+ "name": "Transfer",
+ "parameters": [
+ {
+ "name": "from",
+ "type": "Hash160"
+ },
+ {
+ "name": "to",
+ "type": "Hash160"
+ },
+ {
+ "name": "amount",
+ "type": "Integer"
+ },
+ {
+ "name": "tokenId",
+ "type": "ByteArray"
+ }
+ ]
+ }
+ ]
+ },
+ "permissions": [
+ {
+ "contract": "*",
+ "methods": "*"
+ }
+ ],
+ "trusts": [],
+ "extra": null
+ }
+ }
+ ]
+ }
+ },
+ {
+ "Name": "getrawmempoolasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getrawmempool",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": [ "0x9786cce0dddb524c40ddbdd5e31a41ed1f6b5c8a683c122f627ca4a007a7cf4e", "0xb488ad25eb474f89d5ca3f985cc047ca96bc7373a6d3da8c0f192722896c1cd7" ]
+ }
+ },
+ {
+ "Name": "getrawmempoolbothasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getrawmempool",
+ "params": [ true ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "height": 2846,
+ "verified": [ "0x9786cce0dddb524c40ddbdd5e31a41ed1f6b5c8a683c122f627ca4a007a7cf4e" ],
+ "unverified": [ "0xb488ad25eb474f89d5ca3f985cc047ca96bc7373a6d3da8c0f192722896c1cd7" ]
+ }
+ }
+ },
+ {
+ "Name": "getrawtransactionhexasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getrawtransaction",
+ "params": [ "0x0cfd49c48306f9027dc71585589b6456bcc53567c359fb7858eabca482186b78" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "004cdec1396925aa554712439a9c613ba114efa3fac23ddbca00e1f50500000000466a130000000000311d2000005d030010a5d4e80000000c149903b0c3d292988febe5f306a02f654ea2eb16290c146925aa554712439a9c613ba114efa3fac23ddbca13c00c087472616e736665720c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b523901420c401f85b40d7fa12164aa1d4d18b06ca470f2c89572dc5b901ab1667faebb587cf536454b98a09018adac72376c5e7c5d164535155b763564347aa47b69aa01b3cc290c2103aa052fbcb8e5b33a4eefd662536f8684641f04109f1d5e69cdda6f084890286a0b410a906ad4"
+ }
+ },
+ {
+ "Name": "getrawtransactionasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getrawtransaction",
+ "params": [ "0xc97cc05c790a844f05f582d80952c4ced3894cbe6d96a74f3e5589d741372dd4", true ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0x99eaba3e230702d428ce6bfb4a2dceba6d4cd441f9ca1b7bfe2a418926ae40ab",
+ "size": 252,
+ "version": 0,
+ "nonce": 969006668,
+ "sender": "NikvsLcNP1jWhrFPrfS3n4spEASgdNYTG2",
+ "sysfee": "100000000",
+ "netfee": "1272390",
+ "validuntilblock": 2104625,
+ "signers": [
+ {
+ "account": "0xe19de267a37a71734478f512b3e92c79fc3695fa",
+ "scopes": "CalledByEntry"
+ }
+ ],
+ "attributes": [],
+ "script": "AwAQpdToAAAADBSZA7DD0pKYj\u002Bvl8wagL2VOousWKQwUaSWqVUcSQ5qcYTuhFO\u002Bj\u002BsI928oTwAwIdHJhbnNmZXIMFDt9NxHG8Mz5sdypA9G/odiW8SOMQWJ9W1I5",
+ "witnesses": [
+ {
+ "invocation": "DEAfhbQNf6EhZKodTRiwbKRw8siVctxbkBqxZn\u002Buu1h89TZFS5igkBitrHI3bF58XRZFNRVbdjVkNHqke2mqAbPM",
+ "verification": "DCEDqgUvvLjlszpO79ZiU2\u002BGhGQfBBCfHV5pzdpvCEiQKGoLQQqQatQ="
+ }
+ ],
+ "blockhash": "0xc1ed259e394c9cd93c1e0eb1e0f144c0d10da64861a24c0084f0d98270b698f1",
+ "confirmations": 643,
+ "blocktime": 1579417249620,
+ "vmstate": "HALT"
+ }
+ }
+ },
+ {
+ "Name": "getstorageasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getstorage",
+ "params": [ "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b", "146925aa554712439a9c613ba114efa3fac23ddbca" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "410121064c5d11a2a700"
+ }
+ },
+ {
+ "Name": "getstorageasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getstorage",
+ "params": [ -2, "146925aa554712439a9c613ba114efa3fac23ddbca" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "410121064c5d11a2a700"
+ }
+ },
+ {
+ "Name": "gettransactionheightasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "gettransactionheight",
+ "params": [ "0x0cfd49c48306f9027dc71585589b6456bcc53567c359fb7858eabca482186b78" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": 2226
+ }
+ },
+ {
+ "Name": "getnextblockvalidatorsasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getnextblockvalidators",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": [
+ {
+ "publickey": "03aa052fbcb8e5b33a4eefd662536f8684641f04109f1d5e69cdda6f084890286a",
+ "votes": "0"
+ }
+ ]
+ }
+ },
+
+
+ {
+ "Name": "getconnectioncountasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getconnectioncount",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": 0
+ }
+ },
+ {
+ "Name": "getpeersasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getpeers",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "unconnected": [
+ {
+ "address": "::ffff:70.73.16.236",
+ "port": 10333
+ }
+ ],
+ "bad": [],
+ "connected": [
+ {
+ "address": "::ffff:139.219.106.33",
+ "port": 10333
+ },
+ {
+ "address": "::ffff:47.88.53.224",
+ "port": 10333
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Name": "getversionasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getversion",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "network": 0,
+ "tcpport": 20333,
+ "nonce": 592651621,
+ "useragent": "/Neo:3.0.0-rc1/",
+ "protocol": {
+ "network": 0,
+ "validatorscount": 0,
+ "msperblock": 15000,
+ "maxvaliduntilblockincrement": 1,
+ "maxtraceableblocks": 1,
+ "addressversion": 0,
+ "maxtransactionsperblock": 0,
+ "memorypoolmaxtransactions": 0,
+ "initialgasdistribution": 0,
+ "hardforks": [
+ {
+ "name": "Aspidochelone",
+ "blockheight": 0
+ }
+ ],
+ "standbycommittee": [
+ "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c",
+ "02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093",
+ "03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a",
+ "02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554",
+ "024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d",
+ "02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e",
+ "02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70",
+ "023a36c72844610b4d34d1968662424011bf783ca9d984efa19a20babf5582f3fe",
+ "03708b860c1de5d87f5b151a12c2a99feebd2e8b315ee8e7cf8aa19692a9e18379",
+ "03c6aa6e12638b36e88adc1ccdceac4db9929575c3e03576c617c49cce7114a050",
+ "03204223f8c86b8cd5c89ef12e4f0dbb314172e9241e30c9ef2293790793537cf0",
+ "02a62c915cf19c7f19a50ec217e79fac2439bbaad658493de0c7d8ffa92ab0aa62",
+ "03409f31f0d66bdc2f70a9730b66fe186658f84a8018204db01c106edc36553cd0",
+ "0288342b141c30dc8ffcde0204929bb46aed5756b41ef4a56778d15ada8f0c6654",
+ "020f2887f41474cfeb11fd262e982051c1541418137c02a0f4961af911045de639",
+ "0222038884bbd1d8ff109ed3bdef3542e768eef76c1247aea8bc8171f532928c30",
+ "03d281b42002647f0113f36c7b8efb30db66078dfaaa9ab3ff76d043a98d512fde",
+ "02504acbc1f4b3bdad1d86d6e1a08603771db135a73e61c9d565ae06a1938cd2ad",
+ "0226933336f1b75baa42d42b71d9091508b638046d19abd67f4e119bf64a7cfb4d",
+ "03cdcea66032b82f5c30450e381e5295cae85c5e6943af716cc6b646352a6067dc",
+ "02cd5a5547119e24feaa7c2a0f37b8c9366216bab7054de0065c9be42084003c8a"
+ ],
+ "seedlist": [
+ "seed1.neo.org:10333",
+ "seed2.neo.org:10333",
+ "seed3.neo.org:10333",
+ "seed4.neo.org:10333",
+ "seed5.neo.org:10333"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "Name": "sendrawtransactionasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "sendrawtransaction",
+ "params": [ "ANIHn05ujtUAAAAAACYcEwAAAAAAQkEAAAEKo4e1Ppa3mJpjFDGgVt0fQKBC9gEAXQMAyBeoBAAAAAwUzViuz9M1vh6z0xHh3IAJY9/XLZ8MFAqjh7U+lreYmmMUMaBW3R9AoEL2E8AMCHRyYW5zZmVyDBSlB7dGdv/td+dUuG7NmQnwus08ukFifVtSOAFCDEDh8zgTrGUXyzVX60wBCMyajNRfzFRiEPAe8CgGQ10bA2C3fnVz68Gw+Amgn5gmvuNfYKgWQ/W68Km1bYUPlnEYKQwhA86j4vgfGvk1ItKe3k8kofC+3q1ykzkdM4gPVHXZeHjJC0GVRA14" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0x4d47255ff5564aaa73855068c3574f8f28e2bb18c7fb7256e58ae51fab44c9bc"
+ }
+ }
+ },
+ {
+ "Name": "submitblockasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "submitblock",
+ "params": [ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI+JfEVZZd6cjX2qJADFSuzRR40IzeV3K1zS9Q2wqetqI6hnvVQEAAAAAAAD6lrDvowCyjK9dBALCmE1fvMuahQEAARECAB2sK3wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHKYeUuiB1BN05kD4Gc0RjMFTshpwAABUESPn/oAQABEQ==" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0xa11c9d14748f967178fe22fdcfb829354ae6ccb86824675e147cb128f16d8171"
+ }
+ }
+ },
+
+
+ {
+ "Name": "invokefunctionasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "invokefunction",
+ "params": [
+ "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b",
+ "balanceOf",
+ [
+ {
+ "type": "Hash160",
+ "value": "91b83e96f2a7c4fdf0c1688441ec61986c7cae26"
+ }
+ ]
+ ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "script": "0c1426ae7c6c9861ec418468c1f0fdc4a7f2963eb89111c00c0962616c616e63654f660c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b52",
+ "state": "HALT",
+ "gasconsumed": "2007570",
+ "stack": [
+ {
+ "type": "Integer",
+ "value": "0"
+ }
+ ],
+ "tx": "00d1eb88136925aa554712439a9c613ba114efa3fac23ddbca00e1f50500000000269f1200000000004520200000003e0c1426ae7c6c9861ec418468c1f0fdc4a7f2963eb89111c00c0962616c616e63654f660c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5201420c40794c91299bba340ea2505c777d15ca898f75bcce686461066a2b8018cc1de114a122dcdbc77b447ac7db5fb1584f1533b164fbc8f30ddf5bd6acf016a125e983290c2103aa052fbcb8e5b33a4eefd662536f8684641f04109f1d5e69cdda6f084890286a0b410a906ad4"
+ }
+ }
+ },
+ {
+ "Name": "invokescriptasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "invokescript",
+ "params": [ "EMMMBG5hbWUMFDt9NxHG8Mz5sdypA9G/odiW8SOMQWJ9W1IQwwwGc3ltYm9sDBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtSEMMMCGRlY2ltYWxzDBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtSEMMMC3RvdGFsU3VwcGx5DBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtS" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "script": "EMMMBG5hbWUMFDt9NxHG8Mz5sdypA9G/odiW8SOMQWJ9W1IQwwwGc3ltYm9sDBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtSEMMMCGRlY2ltYWxzDBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtSEMMMC3RvdGFsU3VwcGx5DBQ7fTcRxvDM+bHcqQPRv6HYlvEjjEFifVtS",
+ "state": "HALT",
+ "gasconsumed": "5061560",
+ "stack": [
+ {
+ "type": "Array",
+ "value": [
+ {
+ "type": "ByteString",
+ "value": "dGVzdA=="
+ },
+ {
+ "type": "InteropInterface"
+ },
+ {
+ "type": "Integer",
+ "value": "1"
+ },
+ {
+ "type": "Buffer",
+ "value": "CAwiNQw="
+ },
+ {
+ "type": "Array",
+ "value": [
+ {
+ "type": "ByteString",
+ "value": "YmI="
+ },
+ {
+ "type": "ByteString",
+ "value": "Y2Mw"
+ }
+ ]
+ },
+ {
+ "type": "Map",
+ "value": [
+ {
+ "key": {
+ "type": "Integer",
+ "value": "2"
+ },
+ "value": {
+ "type": "Integer",
+ "value": "12"
+ }
+ },
+ {
+ "key": {
+ "type": "Integer",
+ "value": "0"
+ },
+ "value": {
+ "type": "Integer",
+ "value": "24"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "tx": "00769d16556925aa554712439a9c613ba114efa3fac23ddbca00e1f505000000009e021400000000005620200000009910c30c046e616d650c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5210c30c0673796d626f6c0c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5210c30c08646563696d616c730c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5210c30c0b746f74616c537570706c790c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5201420c40c848d0fcbf5e6a820508242ea8b7ccbeed3caefeed5db570537279c2154f7cfd8b0d8f477f37f4e6ca912935b732684d57c455dff7aa525ad4ab000931f22208290c2103aa052fbcb8e5b33a4eefd662536f8684641f04109f1d5e69cdda6f084890286a0b410a906ad4"
+ }
+ }
+ },
+
+ {
+ "Name": "getunclaimedgasasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getunclaimedgas",
+ "params": [ "NPvKVTGZapmFWABLsyvfreuqn73jCjJtN1" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "unclaimed": "735870007400",
+ "address": "NPvKVTGZapmFWABLsyvfreuqn73jCjJtN1"
+ }
+ }
+ },
+
+ {
+ "Name": "listpluginsasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "listplugins",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": [
+ {
+ "name": "ApplicationLogs",
+ "version": "3.0.0.0",
+ "interfaces": [
+ "IPersistencePlugin"
+ ]
+ },
+ {
+ "name": "LevelDBStore",
+ "version": "3.0.0.0",
+ "interfaces": [
+ "IStoragePlugin"
+ ]
+ },
+ {
+ "name": "RpcNep17Tracker",
+ "version": "3.0.0.0",
+ "interfaces": [
+ "IPersistencePlugin"
+ ]
+ },
+ {
+ "name": "RpcServer",
+ "version": "3.0.0.0",
+ "interfaces": []
+ }
+ ]
+ }
+ },
+ {
+ "Name": "validateaddressasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "validateaddress",
+ "params": [ "NZs2zXSPuuv9ZF6TDGSWT1RBmE8rfGj7UW" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "address": "NZs2zXSPuuv9ZF6TDGSWT1RBmE8rfGj7UW",
+ "isvalid": true
+ }
+ }
+ },
+
+
+ {
+ "Name": "closewalletasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "closewallet",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": true
+ }
+ },
+ {
+ "Name": "dumpprivkeyasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "dumpprivkey",
+ "params": [ "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "KyoYyZpoccbR6KZ25eLzhMTUxREwCpJzDsnuodGTKXSG8fDW9t7x"
+ }
+ },
+ {
+ "Name": "invokescriptasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "invokescript",
+ "params": [
+ "EMAfDAhkZWNpbWFscwwU++3+LtIiZZK2SMTal7nJzV3BpqZBYn1bUg=="
+ ]
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "script": "HxDDDAhkZWNpbWFscwwU++3+LtIiZZK2SMTal7nJzV3BpqZB7vQM2w==",
+ "state": "HALT",
+ "gasconsumed": "999180",
+ "exception": null,
+ "stack": [
+ {
+ "type": "Integer",
+ "value": "8"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Name": "invokescriptasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "invokescript",
+ "params": [
+ "wh8MCGRlY2ltYWxzDBTPduKL0AYsSkeO41VhARMZ88+k0kFifVtS"
+ ]
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "script": "EBEfDAhkZWNpbWFscwwU++3+LtIiZZK2SMTal7nJzV3BpqZBYn1bUg==",
+ "state": "HALT",
+ "gasconsumed": "999180",
+ "exception": null,
+ "stack": [
+ {
+ "type": "Integer",
+ "value": "8"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Name": "getnewaddressasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getnewaddress",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "NXpCs9kcDkPvfyAobNYmFg8yfRZaDopDbf"
+ }
+ },
+ {
+ "Name": "getwalletbalanceasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getwalletbalance",
+ "params": [ "0xd2a4cff31913016155e38e474a2c06d08be276cf" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "balance": "3001101329992600"
+ }
+ }
+ },
+ {
+ "Name": "getwalletunclaimedgasasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getwalletunclaimedgas",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "735870007400"
+ }
+ },
+ {
+ "Name": "importprivkeyasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "importprivkey",
+ "params": [ "KyoYyZpoccbR6KZ25eLzhMTUxREwCpJzDsnuodGTKXSG8fDW9t7x" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "address": "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ",
+ "haskey": true,
+ "label": null,
+ "watchonly": false
+ }
+ }
+ },
+ {
+ "Name": "listaddressasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "listaddress",
+ "params": [],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": [
+ {
+ "address": "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ",
+ "haskey": true,
+ "label": null,
+ "watchonly": false
+ },
+ {
+ "address": "NZs2zXSPuuv9ZF6TDGSWT1RBmE8rfGj7UW",
+ "haskey": true,
+ "label": null,
+ "watchonly": false
+ }
+ ]
+ }
+ },
+ {
+ "Name": "openwalletasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "openwallet",
+ "params": [ "D:\\temp\\3.json", "1111" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": true
+ }
+ },
+ {
+ "Name": "sendfromasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "sendfrom",
+ "params": [ "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b", "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ", "NZs2zXSPuuv9ZF6TDGSWT1RBmE8rfGj7UW", "100.123" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0x035facc3be1fc57da1690e3d2f8214f449d368437d8557ffabb2d408caf9ad76",
+ "size": 272,
+ "version": 0,
+ "nonce": 1553700339,
+ "sender": "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ",
+ "sysfee": "100000000",
+ "netfee": "1272390",
+ "validuntilblock": 2105487,
+ "attributes": [],
+ "signers": [
+ {
+ "account": "0xcadb3dc2faa3ef14a13b619c9a43124755aa2569",
+ "scopes": "CalledByEntry"
+ }
+ ],
+ "script": "A+CSx1QCAAAADBSZA7DD0pKYj+vl8wagL2VOousWKQwUaSWqVUcSQ5qcYTuhFO+j+sI928oTwAwIdHJhbnNmZXIMFDt9NxHG8Mz5sdypA9G/odiW8SOMQWJ9W1I5",
+ "witnesses": [
+ {
+ "invocation": "DEDOA/QF5jYT2TCl9T94fFwAncuBhVhciISaq4fZ3WqGarEoT/0iDo3RIwGjfRW0mm/SV3nAVGEQeZInLqKQ98HX",
+ "verification": "DCEDqgUvvLjlszpO79ZiU2+GhGQfBBCfHV5pzdpvCEiQKGoLQQqQatQ="
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Name": "sendmanyasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "sendmany",
+ "params": [
+ "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ",
+ [
+ {
+ "asset": "0x9bde8f209c88dd0e7ca3bf0af0f476cdd8207789",
+ "value": "10",
+ "address": "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ"
+ },
+ {
+ "asset": "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b",
+ "value": "1.2345",
+ "address": "NZs2zXSPuuv9ZF6TDGSWT1RBmE8rfGj7UW"
+ }
+ ]
+ ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0x542e64a9048bbe1ee565b840c41ccf9b5a1ef11f52e5a6858a523938a20c53ec",
+ "size": 483,
+ "version": 0,
+ "nonce": 34429660,
+ "sender": "NUMK37TV9yYKbJr1Gufh74nZiM623eBLqX",
+ "sysfee": "100000000",
+ "netfee": "2483780",
+ "validuntilblock": 2105494,
+ "attributes": [],
+ "signers": [
+ {
+ "account": "0x36d6200fb4c9737c7b552d2b5530ab43605c5869",
+ "scopes": "CalledByEntry"
+ },
+ {
+ "account": "0x9a55ca1006e2c359bbc8b9b0de6458abdff98b5c",
+ "scopes": "CalledByEntry"
+ }
+ ],
+ "script": "GgwUaSWqVUcSQ5qcYTuhFO+j+sI928oMFGlYXGBDqzBVKy1Ve3xzybQPINY2E8AMCHRyYW5zZmVyDBSJdyDYzXb08Aq/o3wO3YicII/em0FifVtSOQKQslsHDBSZA7DD0pKYj+vl8wagL2VOousWKQwUXIv536tYZN6wuci7WcPiBhDKVZoTwAwIdHJhbnNmZXIMFDt9NxHG8Mz5sdypA9G/odiW8SOMQWJ9W1I5",
+ "witnesses": [
+ {
+ "invocation": "DECOdTEWg1WkuHN0GNV67kwxeuKADyC6TO59vTaU5dK6K1BGt8+EM6L3TdMga4qB2J+Meez8eYwZkSSRubkuvfr9",
+ "verification": "DCECeiS9CyBqFJwNKzonOs/yzajOraFep4IqFJVxBe6TesULQQqQatQ="
+ },
+ {
+ "invocation": "DEB1Laj6lvjoBJLTgE/RdvbJiXOmaKp6eNWDJt+p8kxnW6jbeKoaBRZWfUflqrKV7mZEE2JHA5MxrL5TkRIvsL5K",
+ "verification": "DCECkXL4gxd936eGEDt3KWfIuAsBsQcfyyBUcS8ggF6lZnwLQQqQatQ="
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Name": "sendtoaddressasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "sendtoaddress",
+ "params": [ "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b", "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ", "100.123" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "hash": "0xee5fc3f57d9f9bc9695c88ecc504444aab622b1680b1cb0848d5b6e39e7fd118",
+ "size": 381,
+ "version": 0,
+ "nonce": 330056065,
+ "sender": "NUMK37TV9yYKbJr1Gufh74nZiM623eBLqX",
+ "sysfee": "100000000",
+ "netfee": "2381780",
+ "validuntilblock": 2105500,
+ "attributes": [],
+ "signers": [
+ {
+ "account": "0xcadb3dc2faa3ef14a13b619c9a43124755aa2569",
+ "scopes": "CalledByEntry"
+ }
+ ],
+ "script": "A+CSx1QCAAAADBRpJapVRxJDmpxhO6EU76P6wj3bygwUaSWqVUcSQ5qcYTuhFO+j+sI928oTwAwIdHJhbnNmZXIMFDt9NxHG8Mz5sdypA9G/odiW8SOMQWJ9W1I5",
+ "witnesses": [
+ {
+ "invocation": "DECruSKmQKs0Y2cxplKROjPx8HKiyiYrrPn7zaV9zwHPumLzFc8DvgIo2JxmTnJsORyygN/su8mTmSLLb3PesBvY",
+ "verification": "DCECkXL4gxd936eGEDt3KWfIuAsBsQcfyyBUcS8ggF6lZnwLQQqQatQ="
+ },
+ {
+ "invocation": "DECS5npCs5PwsPUAQ01KyHyCev27dt3kDdT1Vi0K8PwnEoSlxYTOGGQCAwaiNEXSyBdBmT6unhZydmFnkezD7qzW",
+ "verification": "DCEDqgUvvLjlszpO79ZiU2+GhGQfBBCfHV5pzdpvCEiQKGoLQQqQatQ="
+ }
+ ]
+ }
+ }
+ },
+
+
+ {
+ "Name": "getapplicationlogasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getapplicationlog",
+ "params": [ "0x6ea186fe714b8168ede3b78461db8945c06d867da649852352dbe7cbf1ba3724" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "blockhash": "0x6ea186fe714b8168ede3b78461db8945c06d867da649852352dbe7cbf1ba3724",
+ "executions": [
+ {
+ "trigger": "OnPersist",
+ "vmstate": "HALT",
+ "gasconsumed": "2031260",
+ "exception": null,
+ "stack": [],
+ "notifications": [
+ {
+ "contract": "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc",
+ "eventname": "Transfer",
+ "state": {
+ "type": "Array",
+ "value": [
+ {
+ "type": "ByteString",
+ "value": "CqOHtT6Wt5iaYxQxoFbdH0CgQvY="
+ },
+ {
+ "type": "Any"
+ },
+ {
+ "type": "Integer",
+ "value": "18083410"
+ }
+ ]
+ }
+ },
+ {
+ "contract": "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc",
+ "eventname": "Transfer",
+ "state": {
+ "type": "Array",
+ "value": [
+ {
+ "type": "Any"
+ },
+ {
+ "type": "ByteString",
+ "value": "z6LDQN4w1uEMToIZiPSxToNRPog="
+ },
+ {
+ "type": "Integer",
+ "value": "1252390"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "trigger": "PostPersist",
+ "vmstate": "HALT",
+ "gasconsumed": "2031260",
+ "exception": null,
+ "stack": [],
+ "notifications": [
+ {
+ "contract": "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc",
+ "eventname": "Transfer",
+ "state": {
+ "type": "Array",
+ "value": [
+ {
+ "type": "Any"
+ },
+ {
+ "type": "ByteString",
+ "value": "z6LDQN4w1uEMToIZiPSxToNRPog="
+ },
+ {
+ "type": "Integer",
+ "value": "50000000"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Name": "getapplicationlogasync_triggertype",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getapplicationlog",
+ "params": [ "0x6ea186fe714b8168ede3b78461db8945c06d867da649852352dbe7cbf1ba3724", "OnPersist" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "blockhash": "0x6ea186fe714b8168ede3b78461db8945c06d867da649852352dbe7cbf1ba3724",
+ "executions": [
+ {
+ "trigger": "OnPersist",
+ "vmstate": "HALT",
+ "gasconsumed": "2031260",
+ "exception": null,
+ "stack": [],
+ "notifications": [
+ {
+ "contract": "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc",
+ "eventname": "Transfer",
+ "state": {
+ "type": "Array",
+ "value": [
+ {
+ "type": "ByteString",
+ "value": "CqOHtT6Wt5iaYxQxoFbdH0CgQvY="
+ },
+ {
+ "type": "Any"
+ },
+ {
+ "type": "Integer",
+ "value": "18083410"
+ }
+ ]
+ }
+ },
+ {
+ "contract": "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc",
+ "eventname": "Transfer",
+ "state": {
+ "type": "Array",
+ "value": [
+ {
+ "type": "Any"
+ },
+ {
+ "type": "ByteString",
+ "value": "z6LDQN4w1uEMToIZiPSxToNRPog="
+ },
+ {
+ "type": "Integer",
+ "value": "1252390"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ {
+ "Name": "getnep17transfersasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getnep17transfers",
+ "params": [ "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ", 0, 1868595301000 ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "sent": [
+ {
+ "timestamp": 1579250114541,
+ "assethash": "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b",
+ "transferaddress": "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ",
+ "amount": "1000000000",
+ "blockindex": 603,
+ "transfernotifyindex": 0,
+ "txhash": "0x5e177b8d1dc33e9103c0cfd42f6dbf4efbe43029e2d6a18ea5ba0cb8437056b3"
+ },
+ {
+ "timestamp": 1579406581635,
+ "assethash": "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b",
+ "transferaddress": "NUMK37TV9yYKbJr1Gufh74nZiM623eBLqX",
+ "amount": "1000000000",
+ "blockindex": 1525,
+ "transfernotifyindex": 0,
+ "txhash": "0xc9c618b48972b240e0058d97b8d79b807ad51015418c84012765298526aeb77d"
+ }
+ ],
+ "received": [
+ {
+ "timestamp": 1579250114541,
+ "assethash": "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b",
+ "transferaddress": "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ",
+ "amount": "1000000000",
+ "blockindex": 603,
+ "transfernotifyindex": 0,
+ "txhash": "0x5e177b8d1dc33e9103c0cfd42f6dbf4efbe43029e2d6a18ea5ba0cb8437056b3"
+ }
+ ],
+ "address": "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ"
+ }
+ }
+ },
+ {
+ "Name": "getnep17transfersasync_with_null_transferaddress",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getnep17transfers",
+ "params": [ "Ncb7jVsYWBt1q5T5k3ZTP8bn5eK4DuanLd", 0, 1868595301000 ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "sent": [
+ {
+ "timestamp": 1579250114541,
+ "assethash": "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b",
+ "transferaddress": null,
+ "amount": "1000000000",
+ "blockindex": 603,
+ "transfernotifyindex": 0,
+ "txhash": "0x5e177b8d1dc33e9103c0cfd42f6dbf4efbe43029e2d6a18ea5ba0cb8437056b3"
+ },
+ {
+ "timestamp": 1579406581635,
+ "assethash": "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b",
+ "transferaddress": "Ncb7jVsYWBt1q5T5k3ZTP8bn5eK4DuanLd",
+ "amount": "1000000000",
+ "blockindex": 1525,
+ "transfernotifyindex": 0,
+ "txhash": "0xc9c618b48972b240e0058d97b8d79b807ad51015418c84012765298526aeb77d"
+ }
+ ],
+ "received": [
+ {
+ "timestamp": 1579250114541,
+ "assethash": "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b",
+ "transferaddress": null,
+ "amount": "1000000000",
+ "blockindex": 603,
+ "transfernotifyindex": 0,
+ "txhash": "0x5e177b8d1dc33e9103c0cfd42f6dbf4efbe43029e2d6a18ea5ba0cb8437056b3"
+ }
+ ],
+ "address": "Ncb7jVsYWBt1q5T5k3ZTP8bn5eK4DuanLd"
+ }
+ }
+ },
+ {
+ "Name": "getnep17balancesasync",
+ "Request": {
+ "jsonrpc": "2.0",
+ "method": "getnep17balances",
+ "params": [ "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ" ],
+ "id": 1
+ },
+ "Response": {
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": {
+ "balance": [
+ {
+ "assethash": "0x8c23f196d8a1bfd103a9dcb1f9ccf0c611377d3b",
+ "amount": "719978585420",
+ "lastupdatedblock": 3101
+ },
+ {
+ "assethash": "0x9bde8f209c88dd0e7ca3bf0af0f476cdd8207789",
+ "amount": "89999810",
+ "lastupdatedblock": 3096
+ }
+ ],
+ "address": "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ"
+ }
+ }
+ }
+]
diff --git a/benchmarks/Neo.Json.Benchmarks/Neo.Json.Benchmarks.csproj b/benchmarks/Neo.Json.Benchmarks/Neo.Json.Benchmarks.csproj
new file mode 100644
index 0000000000..80c11fde9e
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Neo.Json.Benchmarks.csproj
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
diff --git a/benchmarks/Neo.Json.Benchmarks/Program.cs b/benchmarks/Neo.Json.Benchmarks/Program.cs
new file mode 100644
index 0000000000..16255a17ee
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/Program.cs
@@ -0,0 +1,23 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// Program.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+using BenchmarkDotNet.Running;
+
+// List all benchmarks:
+// dotnet run -c Release --framework [for example: net9.0] -- --list flat(or tree)
+// Run a specific benchmark:
+// dotnet run -c Release --framework [for example: net9.0] -- -f [benchmark name]
+// Run all benchmarks:
+// dotnet run -c Release --framework [for example: net9.0] -- -f *
+// Run all benchmarks of a class:
+// dotnet run -c Release --framework [for example: net9.0] -- -f '*Class*'
+// More options: https://benchmarkdotnet.org/articles/guides/console-args.html
+BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
diff --git a/benchmarks/Neo.Json.Benchmarks/RpcTestCase.cs b/benchmarks/Neo.Json.Benchmarks/RpcTestCase.cs
new file mode 100644
index 0000000000..70ff6967d1
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/RpcTestCase.cs
@@ -0,0 +1,55 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// RpcTestCase.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+namespace Neo.Json.Benchmarks;
+
+public class RpcTestCase
+{
+ public string? Name { get; set; }
+
+ public RpcRequest? Request { get; set; }
+
+ public RpcResponse? Response { get; set; }
+}
+
+public class RpcRequest
+{
+ public JToken? Id { get; set; }
+
+ public string? JsonRpc { get; set; }
+
+ public string? Method { get; set; }
+
+ public JToken[]? Params { get; set; }
+}
+
+public class RpcResponse
+{
+ public JToken? Id { get; set; }
+
+ public string? JsonRpc { get; set; }
+
+ public RpcResponseError? Error { get; set; }
+
+ public JToken? Result { get; set; }
+
+ public string? RawResponse { get; set; }
+
+}
+
+public class RpcResponseError
+{
+ public int Code { get; set; }
+
+ public string? Message { get; set; }
+
+ public JToken? Data { get; set; }
+}
diff --git a/benchmarks/Neo.Json.Benchmarks/RpcTestCaseN.cs b/benchmarks/Neo.Json.Benchmarks/RpcTestCaseN.cs
new file mode 100644
index 0000000000..757213b672
--- /dev/null
+++ b/benchmarks/Neo.Json.Benchmarks/RpcTestCaseN.cs
@@ -0,0 +1,55 @@
+// Copyright (C) 2015-2025 The Neo Project.
+//
+// RpcTestCaseN.cs file belongs to the neo project and is free
+// software distributed under the MIT software license, see the
+// accompanying file LICENSE in the main directory of the
+// repository or http://www.opensource.org/licenses/mit-license.php
+// for more details.
+//
+// Redistribution and use in source and binary forms with or without
+// modifications are permitted.
+
+namespace Neo.Json.Benchmarks;
+
+public class RpcTestCaseN
+{
+ public string? Name { get; set; }
+
+ public RpcRequestN? Request { get; set; }
+
+ public RpcResponseN? Response { get; set; }
+}
+
+public class RpcRequestN
+{
+ public Newtonsoft.Json.Linq.JToken? Id { get; set; }
+
+ public string? JsonRpc { get; set; }
+
+ public string? Method { get; set; }
+
+ public Newtonsoft.Json.Linq.JToken[]? Params { get; set; }
+}
+
+public class RpcResponseN
+{
+ public Newtonsoft.Json.Linq.JToken? Id { get; set; }
+
+ public string? JsonRpc { get; set; }
+
+ public RpcResponseErrorN? Error { get; set; }
+
+ public Newtonsoft.Json.Linq.JToken? Result { get; set; }
+
+ public string? RawResponse { get; set; }
+
+}
+
+public class RpcResponseErrorN
+{
+ public int Code { get; set; }
+
+ public string? Message { get; set; }
+
+ public Newtonsoft.Json.Linq.JToken? Data { get; set; }
+}
diff --git a/docs/handlers.md b/docs/handlers.md
new file mode 100644
index 0000000000..43d864b209
--- /dev/null
+++ b/docs/handlers.md
@@ -0,0 +1,73 @@
+## Neo Core Events
+
+### 1. Block Committing Event
+
+**Event Name** `Committing`
+
+**Handler Interface:** `ICommittingHandler`
+
+This event is triggered when a transaction is in the process of being committed to the blockchain. Implementing the `ICommittingHandler` interface allows you to define custom actions that should be executed during this phase.
+
+### 2. Block Committed Event
+
+**Event Name** `Committed`
+
+**Handler Interface:** `ICommittedHandler`
+
+This event occurs after a transaction has been successfully committed to the blockchain. By implementing the `ICommittedHandler` interface, you can specify custom actions to be performed after the transaction is committed.
+
+### 3. Logging Event
+**Event Name** `Logging`
+
+**Handler Interface:** `ILoggingHandler`
+
+This event is related to logging within the blockchain system. Implement the `ILoggingHandler` interface to define custom logging behaviors for different events and actions that occur in the blockchain.
+
+### 4. General Log Event
+**Event Name** `Log`
+
+**Handler Interface:** `ILogHandler`
+
+This event pertains to general logging activities. The `ILogHandler` interface allows you to handle logging for specific actions or errors within the blockchain system.
+
+### 5. Notification Event
+**Event Name** `Notify`
+
+**Handler Interface:** `INotifyHandler`
+
+This event is triggered when a notification needs to be sent. By implementing the `INotifyHandler` interface, you can specify custom actions for sending notifications when certain events occur within the blockchain system.
+
+### 6. Service Added Event
+**Event Name** `ServiceAdded`
+
+**Handler Interface:** `IServiceAddedHandler`
+
+This event occurs when a new service is added to the blockchain system. Implement the `IServiceAddedHandler` interface to define custom actions that should be executed when a new service is added.
+
+### 7. Transaction Added Event
+**Event Name** `TransactionAdded`
+
+**Handler Interface:** `ITransactionAddedHandler`
+
+This event is triggered when a new transaction is added to the blockchain system. By implementing the `ITransactionAddedHandler` interface, you can specify custom actions to be performed when a new transaction is added.
+
+### 8. Transaction Removed Event
+**Event Name** `TransactionRemoved`
+
+**Handler Interface:** `ITransactionRemovedHandler`
+
+This event occurs when a transaction is removed from the blockchain system. Implement the `ITransactionRemovedHandler` interface to define custom actions that should be taken when a transaction is removed.
+
+### 9. Wallet Changed Event
+**Event Name** `WalletChanged`
+
+**Handler Interface:** `IWalletChangedHandler`
+
+This event is triggered when changes occur in the wallet, such as balance updates or new transactions. By implementing the `IWalletChangedHandler` interface, you can specify custom actions to be taken when there are changes in the wallet.
+
+### 10. Remote Node MessageReceived Event
+**Event Name** `MessageReceived`
+
+**Handler Interface:** `IMessageReceivedHandler`
+
+This event is triggered when a new message is received from a peer remote node.
diff --git a/docs/persistence-architecture.md b/docs/persistence-architecture.md
new file mode 100644
index 0000000000..153ebee0d9
--- /dev/null
+++ b/docs/persistence-architecture.md
@@ -0,0 +1,122 @@
+# Neo Persistence System - Class Relationships
+
+## Interface Hierarchy
+
+```
+IDisposable
+ │
+ ├── IReadOnlyStore
+ ├── IWriteStore
+ └── IStoreProvider
+ │
+ ▼
+ IStore ◄─── IStoreSnapshot
+```
+
+## Class Structure
+
+```
+StoreFactory
+ │
+ ├── MemoryStoreProvider ──creates──> MemoryStore
+ ├── LevelDBStore (Plugin) ──creates──> LevelDBStore
+ └── RocksDBStore (Plugin) ──creates──> RocksDBStore
+ │
+ ▼
+ IStoreSnapshot
+ │
+ ▼
+ Cache Layer
+ │
+ ┌─────────┼─────────┐
+ │ │ │
+ DataCache StoreCache ClonedCache
+```
+
+## Interface Definitions
+
+### IStore
+```csharp
+public interface IStore : IReadOnlyStore, IWriteStore, IDisposable
+{
+ IStoreSnapshot GetSnapshot();
+}
+```
+
+### IStoreSnapshot
+```csharp
+public interface IStoreSnapshot : IReadOnlyStore, IWriteStore, IDisposable
+{
+ IStore Store { get; }
+ void Commit();
+}
+```
+
+### IReadOnlyStore
+```csharp
+public interface IReadOnlyStore where TKey : class?
+{
+ TValue this[TKey key] { get; }
+ bool TryGet(TKey key, out TValue? value);
+ bool Contains(TKey key);
+ IEnumerable<(TKey Key, TValue Value)> Find(TKey? key_prefix = null, SeekDirection direction = SeekDirection.Forward);
+}
+```
+
+### IWriteStore
+```csharp
+public interface IWriteStore
+{
+ void Delete(TKey key);
+ void Put(TKey key, TValue value);
+ void PutSync(TKey key, TValue value) => Put(key, value);
+}
+```
+
+### IStoreProvider
+```csharp
+public interface IStoreProvider
+{
+ string Name { get; }
+ IStore GetStore(string path);
+}
+```
+
+## Core Classes
+
+### StoreFactory
+- Static registry for storage providers
+- Manages provider registration and discovery
+- Creates store instances
+
+## Cache System
+
+### Why Three Cache Classes?
+
+The Neo persistence system uses three cache classes to separate different responsibilities:
+
+1. **DataCache** - Provides common caching infrastructure and change tracking
+2. **StoreCache** - Connects cache to actual storage (database/memory)
+3. **ClonedCache** - Creates isolated copies to prevent data corruption
+
+### Relationships
+
+```
+DataCache (Abstract)
+ │
+ ├── StoreCache ──connects to──> IStore/IStoreSnapshot
+ └── ClonedCache ──wraps──> Any DataCache
+```
+
+### When to Use Each
+
+**StoreCache**:
+- Direct access to storage
+- When you need to read/write to database
+- Base layer for other caches
+
+**ClonedCache**:
+- When you need isolated data manipulation
+- Preventing accidental mutations between components
+- Creating temporary working environments
+- Smart contract execution (isolated from main state)
diff --git a/docs/serialization-format.md b/docs/serialization-format.md
new file mode 100644
index 0000000000..6cbf0f8c95
--- /dev/null
+++ b/docs/serialization-format.md
@@ -0,0 +1,311 @@
+# Neo Serialization Format
+
+This document describes the binary serialization format used by the Neo blockchain platform. The format is designed for efficient serialization and deserialization of blockchain data structures.
+
+## Overview
+
+Neo uses a custom binary serialization format that supports:
+- Primitive data types (integers, booleans, bytes)
+- Variable-length integers (VarInt)
+- Strings (fixed and variable length)
+- Arrays and collections
+- Custom serializable objects
+- Nullable objects
+
+## Core Interfaces
+
+### ISerializable
+
+All serializable objects in Neo implement the `ISerializable` interface:
+
+```csharp
+public interface ISerializable
+{
+ int Size { get; }
+
+ void Serialize(BinaryWriter writer);
+
+ void Deserialize(ref MemoryReader reader);
+}
+```
+
+- `Size`: Returns the serialized size in bytes
+- `Serialize`: Writes the object to a BinaryWriter
+- `Deserialize`: Reads the object from a MemoryReader
+
+## Primitive Data Types
+
+### Integers
+
+Neo supports both little-endian and big-endian integer formats:
+
+| Type | Size | Endianness | Description |
+|------|------|------------|-------------|
+| `sbyte` | 1 byte | N/A | Signed 8-bit integer |
+| `byte` | 1 byte | N/A | Unsigned 8-bit integer |
+| `short` | 2 bytes | Little-endian | Signed 16-bit integer |
+| `ushort` | 2 bytes | Little-endian | Unsigned 16-bit integer |
+| `int` | 4 bytes | Little-endian | Signed 32-bit integer |
+| `uint` | 4 bytes | Little-endian | Unsigned 32-bit integer |
+| `long` | 8 bytes | Little-endian | Signed 64-bit integer |
+| `ulong` | 8 bytes | Little-endian | Unsigned 64-bit integer |
+
+Big-endian variants are available for `short`, `ushort`, `int`, `uint`, `long`, and `ulong`.
+
+### Boolean
+
+Booleans are serialized as single bytes:
+- `false` → `0x00`
+- `true` → `0x01`
+- Any other value throws `FormatException`
+
+### Variable-Length Integers (VarInt)
+
+Neo uses a compact variable-length integer format:
+
+| Value Range | Format | Size |
+|-------------|--------|------|
+| 0-252 | Direct value | 1 byte |
+| 253-65535 | `0xFD` + 2-byte little-endian | 3 bytes |
+| 65536-4294967295 | `0xFE` + 4-byte little-endian | 5 bytes |
+| 4294967296+ | `0xFF` + 8-byte little-endian | 9 bytes |
+
+**Serialization:**
+```csharp
+if (value < 0xFD)
+{
+ writer.Write((byte)value);
+}
+else if (value <= 0xFFFF)
+{
+ writer.Write((byte)0xFD);
+ writer.Write((ushort)value);
+}
+else if (value <= 0xFFFFFFFF)
+{
+ writer.Write((byte)0xFE);
+ writer.Write((uint)value);
+}
+else
+{
+ writer.Write((byte)0xFF);
+ writer.Write(value);
+}
+```
+
+**Deserialization:**
+```csharp
+var b = ReadByte();
+var value = b switch
+{
+ 0xfd => ReadUInt16(),
+ 0xfe => ReadUInt32(),
+ 0xff => ReadUInt64(),
+ _ => b
+};
+```
+
+## Strings
+
+### Fixed-Length Strings
+
+Fixed-length strings are padded with null bytes:
+
+**Format:** `[UTF-8 bytes][zero padding]`
+
+**Serialization:**
+```csharp
+var bytes = value.ToStrictUtf8Bytes();
+if (bytes.Length > length)
+ throw new ArgumentException();
+writer.Write(bytes);
+if (bytes.Length < length)
+ writer.Write(new byte[length - bytes.Length]);
+```
+
+**Deserialization:**
+```csharp
+var end = currentOffset + length;
+var offset = currentOffset;
+while (offset < end && _span[offset] != 0) offset++;
+var data = _span[currentOffset..offset];
+for (; offset < end; offset++)
+ if (_span[offset] != 0)
+ throw new FormatException();
+currentOffset = end;
+return data.ToStrictUtf8String();
+```
+
+### Variable-Length Strings
+
+Variable-length strings use VarInt for length prefix:
+
+**Format:** `[VarInt length][UTF-8 bytes]`
+
+**Serialization:**
+```csharp
+writer.WriteVarInt(value.Length);
+writer.Write(value.ToStrictUtf8Bytes());
+```
+
+**Deserialization:**
+```csharp
+var length = (int)ReadVarInt((ulong)max);
+EnsurePosition(length);
+var data = _span.Slice(currentOffset, length);
+currentOffset += length;
+return data.ToStrictUtf8String();
+```
+
+## Byte Arrays
+
+### Fixed-Length Byte Arrays
+
+**Format:** `[raw bytes]`
+
+### Variable-Length Byte Arrays
+
+**Format:** `[VarInt length][raw bytes]`
+
+**Serialization:**
+```csharp
+writer.WriteVarInt(value.Length);
+writer.Write(value);
+```
+
+**Deserialization:**
+```csharp
+return ReadMemory((int)ReadVarInt((ulong)max));
+```
+
+## Collections
+
+### Serializable Arrays
+
+**Format:** `[VarInt count][item1][item2]...[itemN]`
+
+**Serialization:**
+```csharp
+writer.WriteVarInt(value.Count);
+foreach (T item in value)
+{
+ item.Serialize(writer);
+}
+```
+
+**Deserialization:**
+```csharp
+var array = new T[reader.ReadVarInt((ulong)max)];
+for (var i = 0; i < array.Length; i++)
+{
+ array[i] = new T();
+ array[i].Deserialize(ref reader);
+}
+return array;
+```
+
+### Nullable Arrays
+
+**Format:** `[VarInt count][bool1][item1?][bool2][item2?]...[boolN][itemN?]`
+
+**Serialization:**
+```csharp
+writer.WriteVarInt(value.Length);
+foreach (var item in value)
+{
+ var isNull = item is null;
+ writer.Write(!isNull);
+ if (isNull) continue;
+ item!.Serialize(writer);
+}
+```
+
+**Deserialization:**
+```csharp
+var array = new T[reader.ReadVarInt((ulong)max)];
+for (var i = 0; i < array.Length; i++)
+ array[i] = reader.ReadBoolean() ? reader.ReadSerializable() : null;
+return array;
+```
+
+## UTF-8 Encoding
+
+Neo uses strict UTF-8 encoding with the following characteristics:
+
+- **Strict Mode**: Invalid UTF-8 sequences throw exceptions
+- **No Fallback**: No replacement characters for invalid sequences
+- **Exception Handling**: Detailed error messages for debugging
+
+**String to Bytes:**
+```csharp
+public static byte[] ToStrictUtf8Bytes(this string value)
+{
+ return StrictUTF8.GetBytes(value);
+}
+```
+
+**Bytes to String:**
+```csharp
+public static string ToStrictUtf8String(this ReadOnlySpan value)
+{
+ return StrictUTF8.GetString(value);
+}
+```
+
+## Error Handling
+
+The serialization format includes comprehensive error handling:
+
+- **FormatException**: Invalid data format or corrupted data
+- **ArgumentNullException**: Null values where not allowed
+- **ArgumentException**: Invalid arguments (e.g., string too long)
+- **ArgumentOutOfRangeException**: Values outside allowed ranges
+- **DecoderFallbackException**: Invalid UTF-8 sequences
+- **EncoderFallbackException**: Characters that cannot be encoded
+
+## Examples
+
+### Simple Object Serialization
+
+```csharp
+public class SimpleData : ISerializable
+{
+ public string Name { get; set; }
+ public int Value { get; set; }
+
+ public int Size => Name.GetStrictUtf8ByteCount() + sizeof(int);
+
+ public void Serialize(BinaryWriter writer)
+ {
+ writer.WriteVarString(Name);
+ writer.Write(Value);
+ }
+
+ public void Deserialize(ref MemoryReader reader)
+ {
+ Name = reader.ReadVarString();
+ Value = reader.ReadInt32();
+ }
+}
+```
+
+### Array Serialization
+
+```csharp
+public class DataArray : ISerializable
+{
+ public SimpleData[] Items { get; set; }
+
+ public int Size => Items.Sum(item => item.Size) + GetVarSize(Items.Length);
+
+ public void Serialize(BinaryWriter writer)
+ {
+ writer.Write(Items);
+ }
+
+ public void Deserialize(ref MemoryReader reader)
+ {
+ Items = reader.ReadSerializableArray();
+ }
+}
+```
diff --git a/neo.UnitTests/TestBlockchain.cs b/neo.UnitTests/TestBlockchain.cs
deleted file mode 100644
index 3e7e222b46..0000000000
--- a/neo.UnitTests/TestBlockchain.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-using Neo.Core;
-using Neo.Cryptography.ECC;
-using Neo.IO.Caching;
-using System;
-using System.Collections.Generic;
-
-namespace Neo.UnitTests
-{
- public class TestBlockchain : Blockchain
- {
- private UInt256 _assetId;
-
- ///
- /// Return true if haven't got valid handle
- ///
- public override bool IsDisposed => false;
-
- public TestBlockchain(UInt256 assetId)
- {
- _assetId = assetId;
- }
-
- public override UInt256 CurrentBlockHash => throw new NotImplementedException();
-
- public override UInt256 CurrentHeaderHash => throw new NotImplementedException();
-
- public override uint HeaderHeight => throw new NotImplementedException();
-
- public override uint Height => throw new NotImplementedException();
-
- public override bool AddBlock(Block block)
- {
- throw new NotImplementedException();
- }
-
- public override bool ContainsBlock(UInt256 hash)
- {
- return true; // for verify in UT_Block
- }
-
- public override bool ContainsTransaction(UInt256 hash)
- {
- throw new NotImplementedException();
- }
-
- public override bool ContainsUnspent(UInt256 hash, ushort index)
- {
- throw new NotImplementedException();
- }
-
- public override MetaDataCache GetMetaData()
- {
- return new TestMetaDataCache();
- }
-
- public override DataCache GetStates()
- {
- return new TestDataCache();
- }
-
- public override void Dispose()
- {
- // do nothing
- }
-
- public override AccountState GetAccountState(UInt160 script_hash)
- {
- throw new NotImplementedException();
- }
-
- public override AssetState GetAssetState(UInt256 asset_id)
- {
- if (asset_id == UInt256.Zero) return null;
- UInt160 val = new UInt160(TestUtils.GetByteArray(20, asset_id.ToArray()[0]));
- return new AssetState() { Issuer = val };
- }
-
- public override Block GetBlock(UInt256 hash)
- {
- throw new NotImplementedException();
- }
-
- public override UInt256 GetBlockHash(uint height)
- {
- throw new NotImplementedException();
- }
-
- public override ContractState GetContract(UInt160 hash)
- {
- throw new NotImplementedException();
- }
-
- public override IEnumerable GetEnrollments()
- {
- ECPoint ecp = TestUtils.StandbyValidators[0];
- return new ValidatorState[] { new ValidatorState() { PublicKey = ecp } };
- }
-
- public override Header GetHeader(uint height)
- {
- throw new NotImplementedException();
- }
-
- public override Header GetHeader(UInt256 hash)
- {
- throw new NotImplementedException();
- }
-
- public override Block GetNextBlock(UInt256 hash)
- {
- throw new NotImplementedException();
- }
-
- public override UInt256 GetNextBlockHash(UInt256 hash)
- {
- throw new NotImplementedException();
- }
-
- public override StorageItem GetStorageItem(StorageKey key)
- {
- throw new NotImplementedException();
- }
-
- public override long GetSysFeeAmount(UInt256 hash)
- {
- throw new NotImplementedException();
- }
-
- public override Transaction GetTransaction(UInt256 hash, out int height)
- {
- height = 0;
- // take part of the trans hash and use that for the scripthash of the testtransaction
- return new TestTransaction(_assetId, TransactionType.ClaimTransaction, new UInt160(TestUtils.GetByteArray(20, hash.ToArray()[0])));
- }
-
- public override Dictionary GetUnclaimed(UInt256 hash)
- {
- throw new NotImplementedException();
- }
-
- public override TransactionOutput GetUnspent(UInt256 hash, ushort index)
- {
- throw new NotImplementedException();
- }
-
- public override IEnumerable GetUnspent(UInt256 hash)
- {
- throw new NotImplementedException();
- }
-
- public override bool IsDoubleSpend(Transaction tx)
- {
- throw new NotImplementedException();
- }
-
- protected override void AddHeaders(IEnumerable headers)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/neo.UnitTests/TestDataCache.cs b/neo.UnitTests/TestDataCache.cs
deleted file mode 100644
index d2d3afdabf..0000000000
--- a/neo.UnitTests/TestDataCache.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using Neo.IO;
-using Neo.IO.Caching;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Neo.UnitTests
-{
- public class TestDataCache : DataCache
- where TKey : IEquatable, ISerializable
- where TValue : class, ICloneable, ISerializable, new()
- {
- public override void DeleteInternal(TKey key)
- {
- }
-
- protected override void AddInternal(TKey key, TValue value)
- {
- }
-
- protected override IEnumerable> FindInternal(byte[] key_prefix)
- {
- return Enumerable.Empty>();
- }
-
- protected override TValue GetInternal(TKey key)
- {
- throw new NotImplementedException();
- }
-
- protected override TValue TryGetInternal(TKey key)
- {
- return null;
- }
-
- protected override void UpdateInternal(TKey key, TValue value)
- {
- }
- }
-}
diff --git a/neo.UnitTests/TestMetaDataCache.cs b/neo.UnitTests/TestMetaDataCache.cs
deleted file mode 100644
index b274b25c0a..0000000000
--- a/neo.UnitTests/TestMetaDataCache.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Neo.IO;
-using Neo.IO.Caching;
-
-namespace Neo.UnitTests
-{
- public class TestMetaDataCache : MetaDataCache where T : class, ISerializable, new()
- {
- public TestMetaDataCache()
- : base(null)
- {
- }
-
- protected override T TryGetInternal()
- {
- return null;
- }
- }
-}
diff --git a/neo.UnitTests/TestTransaction.cs b/neo.UnitTests/TestTransaction.cs
deleted file mode 100644
index 6036a8d558..0000000000
--- a/neo.UnitTests/TestTransaction.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using Neo.Core;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- public class TestTransaction : Transaction
- {
- public TestTransaction(UInt256 assetId, TransactionType type, UInt160 scriptHash) : base(type)
- {
- TransactionOutput transVal = new TransactionOutput();
- transVal.Value = Fixed8.FromDecimal(50);
- transVal.AssetId = assetId;
- transVal.ScriptHash = scriptHash;
- base.Outputs = new TransactionOutput[1] { transVal };
- }
- }
-}
diff --git a/neo.UnitTests/TestUtils.cs b/neo.UnitTests/TestUtils.cs
deleted file mode 100644
index ba3c595870..0000000000
--- a/neo.UnitTests/TestUtils.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-using System;
-using Neo.Core;
-using Neo.Cryptography.ECC;
-using Neo.VM;
-using Neo.Wallets;
-using Neo.SmartContract;
-
-namespace Neo.UnitTests
-{
- public static class TestUtils
- {
- public static byte[] GetByteArray(int length, byte firstByte)
- {
- byte[] array = new byte[length];
- array[0] = firstByte;
- for (int i = 1; i < length; i++)
- {
- array[i] = 0x20;
- }
- return array;
- }
-
- public static readonly ECPoint[] StandbyValidators = new ECPoint[] { ECPoint.DecodePoint("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c".HexToBytes(), ECCurve.Secp256r1) };
-
- public static ClaimTransaction GetClaimTransaction()
- {
- return new ClaimTransaction
- {
- Claims = new CoinReference[0],
- Attributes = new TransactionAttribute[0],
- Inputs = new CoinReference[0],
- Outputs = new TransactionOutput[0],
- Scripts = new Witness[0]
- };
- }
-
- public static MinerTransaction GetMinerTransaction()
- {
- return new MinerTransaction
- {
- Nonce = 2083236893,
- Attributes = new TransactionAttribute[0],
- Inputs = new CoinReference[0],
- Outputs = new TransactionOutput[0],
- Scripts = new Witness[0]
- };
- }
-
- public static IssueTransaction GetIssueTransaction(bool inputVal, decimal outputVal, UInt256 assetId)
- {
- TestUtils.SetupTestBlockchain(assetId);
-
- CoinReference[] inputsVal;
- if (inputVal)
- {
- inputsVal = new[]
- {
- TestUtils.GetCoinReference(null)
- };
- }
- else
- {
- inputsVal = new CoinReference[0];
- }
-
- return new IssueTransaction
- {
- Attributes = new TransactionAttribute[0],
- Inputs = inputsVal,
- Outputs = new[]
- {
- new TransactionOutput
- {
- AssetId = assetId,
- Value = Fixed8.FromDecimal(outputVal),
- ScriptHash = Contract.CreateMultiSigRedeemScript(1, TestUtils.StandbyValidators).ToScriptHash()
- }
- },
- Scripts = new[]
- {
- new Witness
- {
- InvocationScript = new byte[0],
- VerificationScript = new[] { (byte)OpCode.PUSHT }
- }
- }
- };
- }
-
- public static CoinReference GetCoinReference(UInt256 prevHash)
- {
- if (prevHash == null) prevHash = UInt256.Zero;
- return new CoinReference
- {
- PrevHash = prevHash,
- PrevIndex = 0
- };
- }
-
- public static void SetupTestBlockchain(UInt256 assetId)
- {
- Blockchain testBlockchain = new TestBlockchain(assetId);
- Blockchain.RegisterBlockchain(testBlockchain);
- }
-
- public static void SetupHeaderWithValues(Header header, UInt256 val256, out UInt256 merkRootVal, out UInt160 val160, out uint timestampVal, out uint indexVal, out ulong consensusDataVal, out Witness scriptVal)
- {
- setupBlockBaseWithValues(header, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal);
- }
-
- public static void SetupBlockWithValues(Block block, UInt256 val256, out UInt256 merkRootVal, out UInt160 val160, out uint timestampVal, out uint indexVal, out ulong consensusDataVal, out Witness scriptVal, out Transaction[] transactionsVal, int numberOfTransactions)
- {
- setupBlockBaseWithValues(block, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal);
-
- transactionsVal = new Transaction[numberOfTransactions];
- if (numberOfTransactions > 0)
- {
- for (int i = 0; i < numberOfTransactions; i++)
- {
- transactionsVal[i] = TestUtils.GetMinerTransaction();
- }
- }
-
- block.Transactions = transactionsVal;
- }
-
- private static void setupBlockBaseWithValues(BlockBase bb, UInt256 val256, out UInt256 merkRootVal, out UInt160 val160, out uint timestampVal, out uint indexVal, out ulong consensusDataVal, out Witness scriptVal)
- {
- bb.PrevHash = val256;
- merkRootVal = new UInt256(new byte[] { 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251 });
- bb.MerkleRoot = merkRootVal;
- timestampVal = new DateTime(1968, 06, 01, 0, 0, 0, DateTimeKind.Utc).ToTimestamp();
- bb.Timestamp = timestampVal;
- indexVal = 0;
- bb.Index = indexVal;
- consensusDataVal = 30;
- bb.ConsensusData = consensusDataVal;
- val160 = UInt160.Zero;
- bb.NextConsensus = val160;
- scriptVal = new Witness
- {
- InvocationScript = new byte[0],
- VerificationScript = new[] { (byte)OpCode.PUSHT }
- };
- bb.Script = scriptVal;
- }
- }
-}
diff --git a/neo.UnitTests/TestVerifiable.cs b/neo.UnitTests/TestVerifiable.cs
deleted file mode 100644
index e02ce3b9ac..0000000000
--- a/neo.UnitTests/TestVerifiable.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using System;
-using System.IO;
-using Neo.Core;
-
-namespace Neo.UnitTests
-{
- public class TestVerifiable : IVerifiable
- {
- private string testStr = "testStr";
-
- public Witness[] Scripts { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
- public int Size => throw new NotImplementedException();
-
- public void Deserialize(BinaryReader reader)
- {
- throw new NotImplementedException();
- }
-
- public void DeserializeUnsigned(BinaryReader reader)
- {
- throw new NotImplementedException();
- }
-
- public byte[] GetMessage()
- {
- throw new NotImplementedException();
- }
-
- public UInt160[] GetScriptHashesForVerifying()
- {
- throw new NotImplementedException();
- }
-
- public void Serialize(BinaryWriter writer)
- {
- throw new NotImplementedException();
- }
-
- public void SerializeUnsigned(BinaryWriter writer)
- {
- writer.Write((string) testStr);
- }
- }
-}
\ No newline at end of file
diff --git a/neo.UnitTests/UT_AccountState.cs b/neo.UnitTests/UT_AccountState.cs
deleted file mode 100644
index 9e18dfef87..0000000000
--- a/neo.UnitTests/UT_AccountState.cs
+++ /dev/null
@@ -1,273 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_AccountState
- {
- AccountState uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new AccountState();
- }
-
- [TestMethod]
- public void ScriptHash_Get()
- {
- uut.ScriptHash.Should().BeNull();
- }
-
- [TestMethod]
- public void ScriptHash_Set()
- {
- UInt160 val = new UInt160();
- uut.ScriptHash = val;
- uut.ScriptHash.Should().Be(val);
- }
-
- [TestMethod]
- public void IsFrozen_Get()
- {
- uut.IsFrozen.Should().Be(false);
- }
-
- [TestMethod]
- public void IsFrozen_Set()
- {
- uut.IsFrozen = true;
- uut.IsFrozen.Should().Be(true);
- }
-
- [TestMethod]
- public void Votes_Get()
- {
- uut.Votes.Should().BeNull();
- }
-
- [TestMethod]
- public void Votes_Set()
- {
- ECPoint val = new ECPoint();
- ECPoint[] array = new ECPoint[] { val };
- uut.Votes = array;
- uut.Votes[0].Should().Be(val);
- }
-
- [TestMethod]
- public void Balances_Get()
- {
- uut.Balances.Should().BeNull();
- }
-
- [TestMethod]
- public void Balances_Set()
- {
- UInt256 key = new UInt256();
- Fixed8 val = new Fixed8();
- Dictionary dict = new Dictionary();
- dict.Add(key, val);
- uut.Balances = dict;
- uut.Balances[key].Should().Be(val);
- }
-
- [TestMethod]
- public void Size_Get_0_Votes_0_Balances()
- {
- UInt160 val = new UInt160();
- ECPoint[] array = new ECPoint[0];
- Dictionary dict = new Dictionary();
-
- uut.ScriptHash = val;
- uut.Votes = array;
- uut.Balances = dict;
-
- uut.Size.Should().Be(24); // 1 + 20 + 1 + 1 + 1 + 0 * (32 + 8)
- }
-
- [TestMethod]
- public void Size_Get_1_Vote_0_Balances()
- {
- UInt160 val = new UInt160();
- ECPoint[] array = new ECPoint[] { new ECPoint() };
- Dictionary dict = new Dictionary();
-
- uut.ScriptHash = val;
- uut.Votes = array;
- uut.Balances = dict;
-
- uut.Size.Should().Be(25); // 1 + 20 + 1 + 2 + 1 + 0 * (32 + 8)
- }
-
- [TestMethod]
- public void Size_Get_5_Votes_0_Balances()
- {
- UInt160 val = new UInt160();
- ECPoint[] array = new ECPoint[] { new ECPoint(), new ECPoint(), new ECPoint(), new ECPoint(), new ECPoint() };
- Dictionary dict = new Dictionary();
-
- uut.ScriptHash = val;
- uut.Votes = array;
- uut.Balances = dict;
-
- uut.Size.Should().Be(29); // 1 + 20 + 1 + 6 + 1 + 0 * (32 + 8)
- }
-
- [TestMethod]
- public void Size_Get_0_Votes_1_Balance()
- {
- UInt160 val = new UInt160();
- ECPoint[] array = new ECPoint[0];
- Dictionary dict = new Dictionary();
- dict.Add(new UInt256(), new Fixed8());
-
- uut.ScriptHash = val;
- uut.Votes = array;
- uut.Balances = dict;
-
- uut.Size.Should().Be(64); // 1 + 20 + 1 + 1 + 1 + 1 * (32 + 8)
- }
-
- [TestMethod]
- public void Size_Get_0_Votes_5_Balance()
- {
- UInt160 val = new UInt160();
- ECPoint[] array = new ECPoint[0];
- Dictionary dict = new Dictionary();
- dict.Add(new UInt256(), new Fixed8());
- dict.Add(new UInt256(TestUtils.GetByteArray(32, 0x20)), new Fixed8());
- dict.Add(new UInt256(TestUtils.GetByteArray(32, 0x21)), new Fixed8());
- dict.Add(new UInt256(TestUtils.GetByteArray(32, 0x22)), new Fixed8());
- dict.Add(new UInt256(TestUtils.GetByteArray(32, 0x23)), new Fixed8());
-
- uut.ScriptHash = val;
- uut.Votes = array;
- uut.Balances = dict;
-
- uut.Size.Should().Be(224); // 1 + 20 + 1 + 1 + 1 + 5 * (32 + 8)
- }
-
- [TestMethod]
- public void Size_Get_5_Votes_5_Balance()
- {
- UInt160 val = new UInt160();
- ECPoint[] array = new ECPoint[] { new ECPoint(), new ECPoint(), new ECPoint(), new ECPoint(), new ECPoint() };
- Dictionary dict = new Dictionary();
- dict.Add(new UInt256(), new Fixed8());
- dict.Add(new UInt256(TestUtils.GetByteArray(32, 0x20)), new Fixed8());
- dict.Add(new UInt256(TestUtils.GetByteArray(32, 0x21)), new Fixed8());
- dict.Add(new UInt256(TestUtils.GetByteArray(32, 0x22)), new Fixed8());
- dict.Add(new UInt256(TestUtils.GetByteArray(32, 0x23)), new Fixed8());
-
- uut.ScriptHash = val;
- uut.Votes = array;
- uut.Balances = dict;
-
- uut.Size.Should().Be(229); // 1 + 20 + 1 + 6 + 1 + 5 * (32 + 8)
- }
-
- private void setupAccountStateWithValues(AccountState accState, out UInt160 scriptHashVal, out ECPoint votesVal, out UInt256 key, out Fixed8 dictVal)
- {
- scriptHashVal = new UInt160();
- accState.ScriptHash = scriptHashVal;
- accState.IsFrozen = true;
- votesVal = new ECPoint();
- ECPoint[] array = new ECPoint[] { votesVal };
- accState.Votes = array;
- key = new UInt256();
- dictVal = new Fixed8();
- Dictionary dict = new Dictionary();
- dict.Add(key, dictVal);
- accState.Balances = dict;
- }
-
- [TestMethod]
- public void Clone()
- {
- UInt160 scriptHashVal;
- ECPoint votesVal;
- UInt256 key;
- Fixed8 dictVal;
- setupAccountStateWithValues(uut, out scriptHashVal, out votesVal, out key, out dictVal);
-
- AccountState newAs = ((ICloneable)uut).Clone();
- newAs.ScriptHash.Should().Be(scriptHashVal);
- newAs.IsFrozen.Should().Be(true);
- newAs.Votes[0].Should().Be(votesVal);
- newAs.Balances.Count.Should().Be(1);
- newAs.Balances.Should().ContainKey(key);
- newAs.Balances[key].Should().Be(dictVal);
- }
-
- [TestMethod]
- public void FromReplica()
- {
- AccountState accState = new AccountState();
- UInt160 scriptHashVal;
- ECPoint votesVal;
- UInt256 key;
- Fixed8 dictVal;
- setupAccountStateWithValues(accState, out scriptHashVal, out votesVal, out key, out dictVal);
-
- ((ICloneable)uut).FromReplica(accState);
- uut.ScriptHash.Should().Be(scriptHashVal);
- uut.IsFrozen.Should().Be(true);
- uut.Votes[0].Should().Be(votesVal);
- uut.Balances.Count.Should().Be(1);
- uut.Balances.Should().ContainKey(key);
- uut.Balances[key].Should().Be(dictVal);
- }
-
- [TestMethod]
- public void Deserialize()
- {
- byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 };
- int index = 0;
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- {
- using (BinaryReader reader = new BinaryReader(ms))
- {
- uut.Deserialize(reader);
- }
- }
- uut.IsFrozen.Should().Be(true);
- }
-
-
- [TestMethod]
- public void Serialize()
- {
- UInt160 scriptHashVal;
- ECPoint votesVal;
- UInt256 key;
- Fixed8 dictVal;
- setupAccountStateWithValues(uut, out scriptHashVal, out votesVal, out key, out dictVal);
-
- byte[] data;
- using (MemoryStream stream = new MemoryStream())
- {
- using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
- {
- uut.Serialize(writer);
- data = stream.ToArray();
- }
- }
-
- byte[] requiredData = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 };
-
- data.Length.Should().Be(25);
- for (int i=0; i<25; i++)
- {
- data[i].Should().Be(requiredData[i]);
- }
- }
- }
-}
diff --git a/neo.UnitTests/UT_AssetState.cs b/neo.UnitTests/UT_AssetState.cs
deleted file mode 100644
index 7dd1bbab95..0000000000
--- a/neo.UnitTests/UT_AssetState.cs
+++ /dev/null
@@ -1,518 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using System.Globalization;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_AssetState
- {
- AssetState uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new AssetState();
- }
-
- [TestMethod]
- public void AssetId_Get()
- {
- uut.AssetId.Should().BeNull();
- }
-
- [TestMethod]
- public void AssetId_Set()
- {
- UInt256 val = new UInt256();
- uut.AssetId = val;
- uut.AssetId.Should().Be(val);
- }
-
- [TestMethod]
- public void AssetType_Get()
- {
- uut.AssetType.Should().Be(AssetType.GoverningToken); // Uninitialised AssetType defaults to this enum value, be careful
- }
-
- [TestMethod]
- public void AssetType_Set()
- {
- AssetType val = new AssetType();
- uut.AssetType = val;
- uut.AssetType.Should().Be(val);
- }
-
- [TestMethod]
- public void Name_Get()
- {
- uut.Name.Should().BeNull();
- }
-
- [TestMethod]
- public void Name_Set()
- {
- string val = "wake up neo";
- uut.Name = val;
- uut.Name.Should().Be(val);
- }
-
- [TestMethod]
- public void Amount_Get()
- {
- uut.Amount.Should().Be(new Fixed8(0)); // defaults to 0
- }
-
- [TestMethod]
- public void Amount_Set()
- {
- Fixed8 val = new Fixed8();
- uut.Amount = val;
- uut.Amount.Should().Be(val);
- }
-
- [TestMethod]
- public void Available_Get()
- {
- uut.Available.Should().Be(new Fixed8(0)); // defaults to 0
- }
-
- [TestMethod]
- public void Available_Set()
- {
- Fixed8 val = new Fixed8();
- uut.Available = val;
- uut.Available.Should().Be(val);
- }
-
- [TestMethod]
- public void Precision_Get()
- {
- uut.Precision.Should().Be(0x00); // defaults to 0
- }
-
- [TestMethod]
- public void Precision_Set()
- {
- byte val = 0x42;
- uut.Precision = val;
- uut.Precision.Should().Be(val);
- }
-
- [TestMethod]
- public void FeeMode_Get()
- {
- AssetState.FeeMode.Should().Be(0);
- }
-
- [TestMethod]
- public void Fee_Get()
- {
- uut.Fee.Should().Be(new Fixed8(0)); // defaults to 0
- }
-
- [TestMethod]
- public void Fee_Set()
- {
- Fixed8 val = new Fixed8();
- uut.Fee = val;
- uut.Fee.Should().Be(val);
- }
-
- [TestMethod]
- public void FeeAddress_Get()
- {
- uut.FeeAddress.Should().BeNull();
- }
-
- [TestMethod]
- public void FeeAddress_Set()
- {
- UInt160 val = new UInt160();
- uut.FeeAddress = val;
- uut.FeeAddress.Should().Be(val);
- }
-
- [TestMethod]
- public void Owner_Get()
- {
- uut.Owner.Should().BeNull();
- }
-
- [TestMethod]
- public void Owner_Set()
- {
- ECPoint val = new ECPoint();
- uut.Owner = val;
- uut.Owner.Should().Be(val);
- }
-
- [TestMethod]
- public void Admin_Get()
- {
- uut.Admin.Should().BeNull();
- }
-
- [TestMethod]
- public void Admin_Set()
- {
- UInt160 val = new UInt160();
- uut.Admin = val;
- uut.Admin.Should().Be(val);
- }
-
- [TestMethod]
- public void Issuer_Get()
- {
- uut.Issuer.Should().BeNull();
- }
-
- [TestMethod]
- public void Issuer_Set()
- {
- UInt160 val = new UInt160();
- uut.Issuer = val;
- uut.Issuer.Should().Be(val);
- }
-
- [TestMethod]
- public void Expiration_Get()
- {
- uut.Expiration.Should().Be(0u);
- }
-
- [TestMethod]
- public void Expiration_Set()
- {
- uint val = 42;
- uut.Expiration = val;
- uut.Expiration.Should().Be(val);
- }
-
- [TestMethod]
- public void IsFrozen_Get()
- {
- uut.IsFrozen.Should().Be(false);
- }
-
- [TestMethod]
- public void IsFrozen_Set()
- {
- uut.IsFrozen = true;
- uut.IsFrozen.Should().Be(true);
- }
-
- private void setupAssetStateWithValues(AssetState assetState, out UInt256 assetId, out AssetType assetType, out string name, out Fixed8 amount, out Fixed8 available, out byte precision, out Fixed8 fee, out UInt160 feeAddress, out ECPoint owner, out UInt160 admin, out UInt160 issuer, out uint expiration, out bool isFrozen)
- {
- assetId = new UInt256(TestUtils.GetByteArray(32, 0x20));
- assetState.AssetId = assetId;
- assetType = AssetType.Token;
- assetState.AssetType = assetType;
-
- name = "neo";
- assetState.Name = name;
-
- amount = new Fixed8(42);
- assetState.Amount = amount;
-
- available = new Fixed8(43);
- assetState.Available = available;
-
- precision = 0x42;
- assetState.Precision = precision;
-
- fee = new Fixed8(44);
- assetState.Fee = fee;
-
- feeAddress = new UInt160(TestUtils.GetByteArray(20, 0x21));
- assetState.FeeAddress = feeAddress;
-
- owner = ECPoint.DecodePoint(TestUtils.GetByteArray(1,0x00), ECCurve.Secp256r1);
- assetState.Owner = owner;
-
- admin = new UInt160(TestUtils.GetByteArray(20, 0x22));
- assetState.Admin = admin;
-
- issuer = new UInt160(TestUtils.GetByteArray(20, 0x23));
- assetState.Issuer = issuer;
-
- expiration = 42u;
- assetState.Expiration = expiration;
-
- isFrozen = true;
- assetState.IsFrozen = isFrozen;
- }
-
- [TestMethod]
- public void Size_Get_Default()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(uut, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
-
- uut.Size.Should().Be(130); // 1 + 32 + 1 + 4 + 8 + 8 + 1 + 1 + 8 + 20 + 1 + 20 + 20 + 4 + 1
- }
-
- [TestMethod]
- public void Clone()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(uut, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
-
- AssetState newAs = ((ICloneable)uut).Clone();
-
- newAs.AssetId.Should().Be(assetId);
- newAs.AssetType.Should().Be(assetType);
- newAs.Name.Should().Be(name);
- newAs.Amount.Should().Be(amount);
- newAs.Available.Should().Be(available);
- newAs.Precision.Should().Be(precision);
- newAs.Fee.Should().Be(fee);
- newAs.FeeAddress.Should().Be(feeAddress);
- newAs.Owner.Should().Be(owner);
- newAs.Admin.Should().Be(admin);
- newAs.Issuer.Should().Be(issuer);
- newAs.Expiration.Should().Be(expiration);
- newAs.IsFrozen.Should().Be(isFrozen);
- }
-
- [TestMethod]
- public void FromReplica()
- {
- AssetState assetState = new AssetState();
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(assetState, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
-
-
- ((ICloneable)uut).FromReplica(assetState);
- uut.AssetId.Should().Be(assetId);
- uut.AssetType.Should().Be(assetType);
- uut.Name.Should().Be(name);
- uut.Amount.Should().Be(amount);
- uut.Available.Should().Be(available);
- uut.Precision.Should().Be(precision);
- uut.Fee.Should().Be(fee);
- uut.FeeAddress.Should().Be(feeAddress);
- uut.Owner.Should().Be(owner);
- uut.Admin.Should().Be(admin);
- uut.Issuer.Should().Be(issuer);
- uut.Expiration.Should().Be(expiration);
- uut.IsFrozen.Should().Be(isFrozen);
- }
-
- [TestMethod]
- public void Deserialize()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(new AssetState(), out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
-
- byte[] data = new byte[] { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96, 3, 110, 101, 111, 42, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 66, 0, 44, 0, 0, 0, 0, 0, 0, 0, 33, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 34, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 42, 0, 0, 0, 1 };
- int index = 0;
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- {
- using (BinaryReader reader = new BinaryReader(ms))
- {
- uut.Deserialize(reader);
- }
- }
-
- uut.AssetId.Should().Be(assetId);
- uut.AssetType.Should().Be(assetType);
- uut.Name.Should().Be(name);
- uut.Amount.Should().Be(amount);
- uut.Available.Should().Be(available);
- uut.Precision.Should().Be(precision);
- uut.Fee.Should().Be(fee);
- uut.FeeAddress.Should().Be(feeAddress);
- uut.Owner.Should().Be(owner);
- uut.Admin.Should().Be(admin);
- uut.Issuer.Should().Be(issuer);
- uut.Expiration.Should().Be(expiration);
- uut.IsFrozen.Should().Be(isFrozen);
- }
-
-
- [TestMethod]
- public void Serialize()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(uut, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
-
- byte[] data;
- using (MemoryStream stream = new MemoryStream())
- {
- using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
- {
- uut.Serialize(writer);
- data = stream.ToArray();
- }
- }
-
- byte[] requiredData = new byte[] { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96, 3, 110, 101, 111, 42, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 66, 0, 44, 0, 0, 0, 0, 0, 0, 0, 33, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 34, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 42, 0, 0, 0, 1 };
- data.Length.Should().Be(130);
- for (int i = 0; i < 130; i++)
- {
- data[i].Should().Be(requiredData[i]);
- }
- }
-
- [TestMethod]
- public void GetName()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(uut, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
-
- uut.GetName().Should().Be("neo");
- // The base class GetName() method should be be optimised to avoid the slow try / catch
- }
-
- [TestMethod]
- public void GetName_Culture()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(uut, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
- uut.Name = "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"Neo\"}]";
-
- uut.GetName(new CultureInfo("zh-CN")).Should().Be("小蚁股");
- uut.GetName(new CultureInfo("en")).Should().Be("Neo");
- }
-
- [TestMethod]
- public void GetName_Culture_En()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(uut, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
- uut.Name = "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"Neo\"}]";
-
- CultureInfo.CurrentCulture = new CultureInfo("en");
- uut.GetName().Should().Be("Neo");
- }
-
- [TestMethod]
- public void GetName_Culture_Cn()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(uut, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
- uut.Name = "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"Neo\"}]";
-
- CultureInfo.CurrentCulture = new CultureInfo("zh-CN");
- uut.GetName().Should().Be("小蚁股");
- }
-
- [TestMethod]
- public void GetName_Culture_Unknown()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(uut, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
- uut.Name = "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"Neo\"}]";
-
- CultureInfo.CurrentCulture = new CultureInfo("de-DE");
- uut.GetName().Should().Be("Neo"); // defaults to english IF english is in the name
- }
-
- [TestMethod]
- public void GetName_Culture_Unknown_NoEn()
- {
- UInt256 assetId;
- AssetType assetType;
- string name;
- Fixed8 amount, available, fee;
- byte precision;
- UInt160 feeAddress, admin, issuer;
- ECPoint owner;
- uint expiration;
- bool isFrozen;
- setupAssetStateWithValues(uut, out assetId, out assetType, out name, out amount, out available, out precision, out fee, out feeAddress, out owner, out admin, out issuer, out expiration, out isFrozen);
- uut.Name = "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"foo\",\"name\":\"bar\"}]";
-
- CultureInfo.CurrentCulture = new CultureInfo("de-DE");
- uut.GetName().Should().Be("小蚁股"); // defaults to first name IF english is not in the name
- }
-
-
- }
-}
diff --git a/neo.UnitTests/UT_Block.cs b/neo.UnitTests/UT_Block.cs
deleted file mode 100644
index fce6367bab..0000000000
--- a/neo.UnitTests/UT_Block.cs
+++ /dev/null
@@ -1,640 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO.Json;
-using Neo.SmartContract;
-using Neo.VM;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_Block
- {
- Block uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new Block();
- }
-
- [TestMethod]
- public void Transactions_Get()
- {
- uut.Transactions.Should().BeNull();
- }
-
- [TestMethod]
- public void Transactions_Set()
- {
- Transaction[] val = new Transaction[10];
- uut.Transactions = val;
- uut.Transactions.Length.Should().Be(10);
- }
-
-
-
- [TestMethod]
- public void Header_Get()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Header.Should().NotBeNull();
- uut.Header.PrevHash.Should().Be(val256);
- uut.Header.MerkleRoot.Should().Be(merkRootVal);
- uut.Header.Timestamp.Should().Be(timestampVal);
- uut.Header.Index.Should().Be(indexVal);
- uut.Header.ConsensusData.Should().Be(consensusDataVal);
- uut.Header.Script.Should().Be(scriptVal);
- }
-
- [TestMethod]
- public void Size_Get()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
- // blockbase 4 + 32 + 32 + 4 + 4 + 8 + 20 + 1 + 3
- // block 1
- uut.Size.Should().Be(109);
- }
-
- private IssueTransaction getIssueTransaction(bool inputVal, decimal outputVal, UInt256 assetId)
- {
- TestUtils.SetupTestBlockchain(assetId);
-
- CoinReference[] inputsVal;
- if (inputVal)
- {
- inputsVal = new[]
- {
- TestUtils.GetCoinReference(null)
- };
- }
- else
- {
- inputsVal = new CoinReference[0];
- }
-
-
- return new IssueTransaction
- {
- Attributes = new TransactionAttribute[0],
- Inputs = inputsVal,
- Outputs = new[]
- {
- new TransactionOutput
- {
- AssetId = assetId,
- Value = Fixed8.FromDecimal(outputVal),
- ScriptHash = Contract.CreateMultiSigRedeemScript(1, TestUtils.StandbyValidators).ToScriptHash()
- }
- },
- Scripts = new[]
- {
- new Witness
- {
- InvocationScript = new byte[0],
- VerificationScript = new[] { (byte)OpCode.PUSHT }
- }
- }
- };
- }
-
- private ContractTransaction getContractTransaction(bool inputVal, decimal outputVal, UInt256 assetId)
- {
- TestUtils.SetupTestBlockchain(assetId);
-
- CoinReference[] inputsVal;
- if (inputVal)
- {
- inputsVal = new[]
- {
- TestUtils.GetCoinReference(null)
- };
- }
- else
- {
- inputsVal = new CoinReference[0];
- }
-
- return new ContractTransaction
- {
- Attributes = new TransactionAttribute[0],
- Inputs = inputsVal,
- Outputs = new[]
- {
- new TransactionOutput
- {
- AssetId = assetId,
- Value = Fixed8.FromDecimal(outputVal),
- ScriptHash = Contract.CreateMultiSigRedeemScript(1, TestUtils.StandbyValidators).ToScriptHash()
- }
- },
- Scripts = new[]
- {
- new Witness
- {
- InvocationScript = new byte[0],
- VerificationScript = new[] { (byte)OpCode.PUSHT }
- }
- }
- };
- }
-
-
-
- [TestMethod]
- public void Size_Get_1_Transaction()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Transactions = new Transaction[1] {
- TestUtils.GetMinerTransaction()
- };
-
- // blockbase 4 + 32 + 32 + 4 + 4 + 8 + 20 + 1 + 3
- // block 11
- uut.Size.Should().Be(119);
- }
-
- [TestMethod]
- public void Size_Get_3_Transaction()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Transactions = new Transaction[3] {
- TestUtils.GetMinerTransaction(),
- TestUtils.GetMinerTransaction(),
- TestUtils.GetMinerTransaction()
- };
-
- // blockbase 4 + 32 + 32 + 4 + 4 + 8 + 20 + 1 + 3
- // block 31
- uut.Size.Should().Be(139);
- }
-
- [TestMethod]
- public void CalculateNetFee_EmptyTransactions()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- Block.CalculateNetFee(uut.Transactions).Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void CalculateNetFee_Ignores_MinerTransactions()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Transactions = new Transaction[1] {
- TestUtils.GetMinerTransaction()
- };
-
- Block.CalculateNetFee(uut.Transactions).Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void CalculateNetFee_Ignores_ClaimTransactions()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Transactions = new Transaction[1] {
- TestUtils.GetClaimTransaction()
- };
-
- Block.CalculateNetFee(uut.Transactions).Should().Be(Fixed8.Zero);
- }
-
-
- [TestMethod]
- public void CalculateNetFee_Out()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Transactions = new Transaction[1] {
- getContractTransaction(false, 100, Blockchain.UtilityToken.Hash)
- };
-
- Block.CalculateNetFee(uut.Transactions).Should().Be(Fixed8.FromDecimal(-100));
- }
-
- [TestMethod]
- public void CalculateNetFee_In()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Transactions = new Transaction[1] {
- getContractTransaction(true, 0, Blockchain.UtilityToken.Hash)
- };
-
- Block.CalculateNetFee(uut.Transactions).Should().Be(Fixed8.FromDecimal(50));
- }
-
- [TestMethod]
- public void CalculateNetFee_In_And_Out()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Transactions = new Transaction[1] {
- getContractTransaction(true, 100, Blockchain.UtilityToken.Hash)
- };
-
- Block.CalculateNetFee(uut.Transactions).Should().Be(Fixed8.FromDecimal(-50));
- }
-
- [TestMethod]
- public void CalculateNetFee_SystemFee()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Transactions = new Transaction[1] {
- TestUtils.GetIssueTransaction(true, 0, new UInt256(TestUtils.GetByteArray(32, 0x42)))
- };
-
- Block.CalculateNetFee(uut.Transactions).Should().Be(Fixed8.FromDecimal(-500));
- }
-
- [TestMethod]
- public void Serialize()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
-
- byte[] data;
- using (MemoryStream stream = new MemoryStream())
- {
- using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
- {
- uut.Serialize(writer);
- data = stream.ToArray();
- }
- }
-
- byte[] requiredData = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 128, 171, 4, 253, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 81, 1, 0, 0, 29, 172, 43, 124, 0, 0, 0, 0 };
-
- data.Length.Should().Be(119);
- for (int i = 0; i < 119; i++)
- {
- data[i].Should().Be(requiredData[i]);
- }
- }
-
- [TestMethod]
- public void Deserialize()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(new Block(), val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
-
- uut.MerkleRoot = merkRoot; // need to set for deserialise to be valid
-
- byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 128, 171, 4, 253, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 81, 1, 0, 0, 29, 172, 43, 124, 0, 0, 0, 0 };
- int index = 0;
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- {
- using (BinaryReader reader = new BinaryReader(ms))
- {
- uut.Deserialize(reader);
- }
- }
-
- assertStandardBlockTestVals(val256, merkRoot, val160, timestampVal, indexVal, consensusDataVal, scriptVal, transactionsVal);
- }
-
- private void assertStandardBlockTestVals(UInt256 val256, UInt256 merkRoot, UInt160 val160, uint timestampVal, uint indexVal, ulong consensusDataVal, Witness scriptVal, Transaction[] transactionsVal, bool testTransactions = true)
- {
- uut.PrevHash.Should().Be(val256);
- uut.MerkleRoot.Should().Be(merkRoot);
- uut.Timestamp.Should().Be(timestampVal);
- uut.Index.Should().Be(indexVal);
- uut.ConsensusData.Should().Be(consensusDataVal);
- uut.NextConsensus.Should().Be(val160);
- uut.Script.InvocationScript.Length.Should().Be(0);
- uut.Script.Size.Should().Be(scriptVal.Size);
- uut.Script.VerificationScript[0].Should().Be(scriptVal.VerificationScript[0]);
- if (testTransactions)
- {
- uut.Transactions.Length.Should().Be(1);
- uut.Transactions[0].Should().Be(transactionsVal[0]);
- }
- }
-
- [TestMethod]
- public void Equals_SameObj()
- {
- uut.Equals(uut).Should().BeTrue();
- }
-
- [TestMethod]
- public void Equals_DiffObj()
- {
- Block newBlock = new Block();
- UInt256 val256 = UInt256.Zero;
- UInt256 prevHash = new UInt256(TestUtils.GetByteArray(32, 0x42));
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(newBlock, val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
- TestUtils.SetupBlockWithValues(uut, prevHash, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 0);
-
- uut.Equals(newBlock).Should().BeFalse();
- }
-
- [TestMethod]
- public void Equals_Null()
- {
- uut.Equals(null).Should().BeFalse();
- }
-
- [TestMethod]
- public void Equals_SameHash()
- {
-
- Block newBlock = new Block();
- UInt256 prevHash = new UInt256(TestUtils.GetByteArray(32, 0x42));
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(newBlock, prevHash, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
- TestUtils.SetupBlockWithValues(uut, prevHash, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
-
- uut.Equals(newBlock).Should().BeTrue();
- }
-
- [TestMethod]
- public void Trim()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
-
- byte[] data = uut.Trim();
- byte[] requiredData = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 128, 171, 4, 253, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 81, 1, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251 };
-
- data.Length.Should().Be(141);
- for (int i = 0; i < 141; i++)
- {
- data[i].Should().Be(requiredData[i]);
- }
- }
-
- [TestMethod]
- public void FromTrimmedData()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(new Block(), val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
-
- byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 128, 171, 4, 253, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 81, 1, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251 };
-
- uut = Block.FromTrimmedData(data, 0, x => TestUtils.GetMinerTransaction());
-
- assertStandardBlockTestVals(val256, merkRoot, val160, timestampVal, indexVal, consensusDataVal, scriptVal, transactionsVal);
- uut.Transactions[0].Should().Be(TestUtils.GetMinerTransaction());
- }
-
- [TestMethod]
- public void FromTrimmedData_MultipleTx()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(new Block(), val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 3);
-
- byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 128, 171, 4, 253, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 81, 3, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251 };
-
- uut = Block.FromTrimmedData(data, 0, x => TestUtils.GetMinerTransaction());
-
- assertStandardBlockTestVals(val256, merkRoot, val160, timestampVal, indexVal, consensusDataVal, scriptVal, transactionsVal, testTransactions: false);
- uut.Transactions.Length.Should().Be(3);
- uut.Transactions[0].Should().Be(TestUtils.GetMinerTransaction());
- uut.Transactions[1].Should().Be(TestUtils.GetMinerTransaction());
- uut.Transactions[2].Should().Be(TestUtils.GetMinerTransaction());
- }
-
- [TestMethod]
- public void RebuildMerkleRoot_Updates()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
-
- UInt256 merkleRoot = uut.MerkleRoot;
-
- TestUtils.SetupBlockWithValues(uut, val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 3);
- uut.RebuildMerkleRoot();
-
- uut.MerkleRoot.Should().NotBe(merkleRoot);
- }
-
- [TestMethod]
- public void ToJson()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
-
- JObject jObj = uut.ToJson();
- jObj.Should().NotBeNull();
- jObj["hash"].AsString().Should().Be("0x4520462a8c80056291f871da523bff0eb17e29d44ab4317e69ff7a42083cb39d");
- jObj["size"].AsNumber().Should().Be(119);
- jObj["version"].AsNumber().Should().Be(0);
- jObj["previousblockhash"].AsString().Should().Be("0x0000000000000000000000000000000000000000000000000000000000000000");
- jObj["merkleroot"].AsString().Should().Be("0xfb5bd72b2d6792d75dc2f1084ffa9e9f70ca85543c717a6b13d9959b452a57d6");
- jObj["time"].AsNumber().Should().Be(4244941696);
- jObj["index"].AsNumber().Should().Be(0);
- jObj["nonce"].AsString().Should().Be("000000000000001e");
- jObj["nextconsensus"].AsString().Should().Be("AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM");
-
- JObject scObj = jObj["script"];
- scObj["invocation"].AsString().Should().Be("");
- scObj["verification"].AsString().Should().Be("51");
-
- jObj["tx"].Should().NotBeNull();
- JArray txObj = (JArray)jObj["tx"];
- txObj[0]["txid"].AsString().Should().Be("0xfb5bd72b2d6792d75dc2f1084ffa9e9f70ca85543c717a6b13d9959b452a57d6");
- txObj[0]["size"].AsNumber().Should().Be(10);
- txObj[0]["type"].AsString().Should().Be("MinerTransaction");
- txObj[0]["version"].AsNumber().Should().Be(0);
- ((JArray)txObj[0]["attributes"]).Count.Should().Be(0);
- ((JArray)txObj[0]["vin"]).Count.Should().Be(0);
- ((JArray)txObj[0]["vout"]).Count.Should().Be(0);
- txObj[0]["sys_fee"].AsString().Should().Be("0");
- txObj[0]["net_fee"].AsString().Should().Be("0");
- ((JArray)txObj[0]["scripts"]).Count.Should().Be(0);
- txObj[0]["nonce"].AsNumber().Should().Be(2083236893);
- }
-
- [TestMethod]
- public void Verify_CompletelyFalse()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
-
- TestUtils.SetupTestBlockchain(UInt256.Zero);
-
- uut.Verify(false).Should().BeTrue();
- }
-
- [TestMethod]
- public void Verify_CompletelyFalse_MinerTransaction_After_First()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 3);
-
- TestUtils.SetupTestBlockchain(UInt256.Zero);
-
- uut.Verify(false).Should().BeFalse();
- }
-
- [TestMethod]
- public void Verify_CompletelyTrue_NextConsensus_Fail()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- Transaction[] transactionsVal;
- TestUtils.SetupBlockWithValues(uut, val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal, out transactionsVal, 1);
- // passing NextConsensus below
- // uut.NextConsensus = new UInt160(new byte[] { 23, 52, 98, 203, 0, 206, 138, 37, 140, 16, 251, 231, 61, 120, 218, 200, 182, 125, 120, 73 });
-
- TestUtils.SetupTestBlockchain(UInt256.Zero);
-
- uut.Verify(true).Should().BeFalse();
- }
- }
-}
diff --git a/neo.UnitTests/UT_ClaimTransaction.cs b/neo.UnitTests/UT_ClaimTransaction.cs
deleted file mode 100644
index 969b166abb..0000000000
--- a/neo.UnitTests/UT_ClaimTransaction.cs
+++ /dev/null
@@ -1,160 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO.Json;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_ClaimTransaction
- {
- ClaimTransaction uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new ClaimTransaction();
- }
-
- [TestMethod]
- public void Claims_Get()
- {
- uut.Claims.Should().BeNull();
- }
-
- [TestMethod]
- public void Claims_Set()
- {
- CoinReference val = new CoinReference();
- CoinReference[] refs = new CoinReference[] { val };
- uut.Claims = refs;
- uut.Claims.Length.Should().Be(1);
- uut.Claims[0].Should().Be(val);
- }
-
- [TestMethod]
- public void NetworkFee_Get()
- {
- uut.NetworkFee.Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void Size__Get_0_Claims()
- {
- CoinReference[] refs = new CoinReference[0];
- uut.Claims = refs;
-
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- uut.Size.Should().Be(7); // 1, 1, 1, 1, 1, 1 + claims 1
- }
-
- [TestMethod]
- public void Size__Get_1_Claims()
- {
- CoinReference[] refs = new[] { TestUtils.GetCoinReference(null) };
- uut.Claims = refs;
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- uut.Size.Should().Be(41); // 1, 1, 1, 1, 1, 1 + claims 35
- }
-
- [TestMethod]
- public void Size__Get_3_Claims()
- {
- CoinReference[] refs = new[] { TestUtils.GetCoinReference(null), TestUtils.GetCoinReference(null), TestUtils.GetCoinReference(null) };
- uut.Claims = refs;
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- uut.Size.Should().Be(109); // 1, 1, 1, 1, 1, 1 + claims 103
- }
-
- [TestMethod]
- public void GetScriptHashesForVerifying_0_Claims()
- {
- uut.Claims = new CoinReference[0];
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- uut.GetScriptHashesForVerifying().Length.Should().Be(0);
- }
-
- [TestMethod]
- public void GetScriptHashesForVerifying_1_Claim()
- {
- CoinReference[] refs = new[] { TestUtils.GetCoinReference(new UInt256(TestUtils.GetByteArray(32, 0x42))) };
- uut.Claims = refs;
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- TestUtils.SetupTestBlockchain(UInt256.Zero);
-
- UInt160[] res = uut.GetScriptHashesForVerifying();
- res.Length.Should().Be(1);
- }
-
-
- [TestMethod]
- public void GetScriptHashesForVerifying_2_Claim()
- {
- CoinReference[] refs = new[] { TestUtils.GetCoinReference(new UInt256(TestUtils.GetByteArray(32, 0x42))), TestUtils.GetCoinReference(new UInt256(TestUtils.GetByteArray(32, 0x48))) };
- uut.Claims = refs;
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- TestUtils.SetupTestBlockchain(UInt256.Zero);
-
- UInt160[] res = uut.GetScriptHashesForVerifying();
- res.Length.Should().Be(2);
- }
-
- [TestMethod]
- public void ToJson()
- {
- CoinReference[] refs = new[] { TestUtils.GetCoinReference(new UInt256(TestUtils.GetByteArray(32, 0x42))) };
- uut.Claims = refs;
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- JObject jObj = uut.ToJson();
- jObj.Should().NotBeNull();
- jObj["txid"].AsString().Should().Be("0x45a5c537ca95d62add6b331cad0fd742ce29ada02c50ea7e4d709f83563972b9");
- jObj["size"].AsNumber().Should().Be(41);
- jObj["type"].AsString().Should().Be("ClaimTransaction");
- jObj["version"].AsNumber().Should().Be(0);
- ((JArray)jObj["attributes"]).Count.Should().Be(0);
- ((JArray)jObj["vin"]).Count.Should().Be(0);
- ((JArray)jObj["vout"]).Count.Should().Be(0);
- jObj["sys_fee"].AsString().Should().Be("0");
- jObj["net_fee"].AsString().Should().Be("0");
- ((JArray)jObj["scripts"]).Count.Should().Be(0);
-
- JArray claims = (JArray) jObj["claims"];
- claims.Count.Should().Be(1);
- claims[0]["txid"].AsString().Should().Be("0x2020202020202020202020202020202020202020202020202020202020202042");
- claims[0]["vout"].AsNumber().Should().Be(0);
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_CoinReference.cs b/neo.UnitTests/UT_CoinReference.cs
deleted file mode 100644
index e850285542..0000000000
--- a/neo.UnitTests/UT_CoinReference.cs
+++ /dev/null
@@ -1,206 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using System.IO;
-using Neo.IO;
-using Neo.IO.Json;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_CoinReference
- {
- CoinReference uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new CoinReference();
- }
-
- [TestMethod]
- public void PrevHash_Get()
- {
- uut.PrevHash.Should().BeNull();
- }
-
- [TestMethod]
- public void PrevHash_Set()
- {
- UInt256 val = new UInt256(TestUtils.GetByteArray(32, 0x42));
- uut.PrevHash = val;
-
- uut.PrevHash.Should().Be(val);
- }
-
- [TestMethod]
- public void PrevIndex_Get()
- {
- uut.PrevIndex.Should().Be(0);
- }
-
- [TestMethod]
- public void PrevIndex_Set()
- {
- ushort val = 42;
- uut.PrevIndex = val;
-
- uut.PrevIndex.Should().Be(val);
- }
-
- [TestMethod]
- public void Size()
- {
- uut.PrevHash = new UInt256(TestUtils.GetByteArray(32, 0x42));
- uut.Size.Should().Be(34);
- }
-
- private void setupCoinReferenceWithVals(CoinReference coinRef, out UInt256 prevHashVal, out ushort prevIndexVal)
- {
- prevHashVal = new UInt256(TestUtils.GetByteArray(32, 0x42));
- prevIndexVal = 22;
- coinRef.PrevHash = prevHashVal;
- coinRef.PrevIndex = prevIndexVal;
- }
-
- [TestMethod]
- public void Serialize()
- {
- UInt256 prevHashVal;
- ushort prevIndexVal;
- setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
-
- byte[] data;
- using (MemoryStream stream = new MemoryStream())
- {
- using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
- {
- ((ISerializable)uut).Serialize(writer);
- data = stream.ToArray();
- }
- }
-
- byte[] requiredData = new byte[] { 66, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 22, 0 };
- data.Length.Should().Be(34);
- for (int i = 0; i < 34; i++)
- {
- data[i].Should().Be(requiredData[i]);
- }
- }
-
- [TestMethod]
- public void Deserialize()
- {
- UInt256 prevHashVal;
- ushort prevIndexVal;
- setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
-
- byte[] data = new byte[] { 66, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 22, 0 };
- int index = 0;
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- {
- using (BinaryReader reader = new BinaryReader(ms))
- {
- ((ISerializable)uut).Deserialize(reader);
- }
- }
-
- uut.PrevHash.Should().Be(prevHashVal);
- uut.PrevIndex.Should().Be(prevIndexVal);
- }
-
- [TestMethod]
- public void Equals_SameObj()
- {
- uut.Equals(uut).Should().BeTrue();
- }
-
- [TestMethod]
- public void Equals_Null()
- {
- uut.Equals(null).Should().BeFalse();
- }
-
- [TestMethod]
- public void Equals_SameHash()
- {
-
- UInt256 prevHashVal;
- ushort prevIndexVal;
- setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
- CoinReference newCoinRef = new CoinReference();
- setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal);
-
- uut.Equals(newCoinRef).Should().BeTrue();
- }
-
- [TestMethod]
- public void Equals_DiffHash()
- {
-
- UInt256 prevHashVal;
- ushort prevIndexVal;
- setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
- CoinReference newCoinRef = new CoinReference();
- setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal);
- newCoinRef.PrevHash = new UInt256(TestUtils.GetByteArray(32, 0x78));
-
- uut.Equals(newCoinRef).Should().BeFalse();
- }
-
-
- [TestMethod]
- public void Equals_SameIndex()
- {
-
- UInt256 prevHashVal;
- ushort prevIndexVal;
- setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
- CoinReference newCoinRef = new CoinReference();
- setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal);
-
- uut.Equals(newCoinRef).Should().BeTrue();
- }
-
- [TestMethod]
- public void Equals_DiffIndex()
- {
-
- UInt256 prevHashVal;
- ushort prevIndexVal;
- setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
- CoinReference newCoinRef = new CoinReference();
- setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal);
- newCoinRef.PrevIndex = 73;
-
- uut.Equals(newCoinRef).Should().BeFalse();
- }
-
- [TestMethod]
- public void Class_GetHashCode()
- {
- UInt256 prevHashVal;
- ushort prevIndexVal;
- setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
-
- uut.GetHashCode().Should().Be(538976344);
- }
-
- [TestMethod]
- public void ToJson()
- {
- UInt256 prevHashVal;
- ushort prevIndexVal;
- setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
-
- JObject jObj = uut.ToJson();
- jObj.Should().NotBeNull();
- jObj["txid"].AsString().Should().Be("0x2020202020202020202020202020202020202020202020202020202020202042");
- jObj["vout"].AsNumber().Should().Be(prevIndexVal);
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_Culture.cs b/neo.UnitTests/UT_Culture.cs
deleted file mode 100644
index f1b2fcb57b..0000000000
--- a/neo.UnitTests/UT_Culture.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_Culture
- {
- // This test runs all the other unit tests in the project, with a variety of cultures
- // This test will fail when any other test in the project fails. Fix the other failing test(s) and this test should pass again.
- [TestMethod]
- [NotReRunnable]
- public void All_Tests_Cultures()
- {
- // get all tests in the unit test project assembly
- var testClasses = (from t in typeof(NotReRunnableAttribute).GetTypeInfo().Assembly.DefinedTypes
- where t.GetCustomAttribute() != null
- select new
- {
- Constructor = t.GetConstructor(new Type[] { }),
- ClassInit = t.GetMethods().Where(
- m => m.GetCustomAttribute() != null).SingleOrDefault(),
- TestInit = t.GetMethods().Where(
- m => m.GetCustomAttribute() != null).SingleOrDefault(),
- TestCleanup = t.GetMethods().Where(
- m => m.GetCustomAttribute() != null).SingleOrDefault(),
- ClassCleanup = t.GetMethods().Where(
- m => m.GetCustomAttribute() != null).SingleOrDefault(),
- TestMethods = t.GetMethods().Where(
- m => m.GetCustomAttribute() != null
- && m.GetCustomAttribute() == null).ToList()
- }).ToList();
-
- var cultures = new string[] { "en-US", "zh-CN", "de-DE", "ko-KR", "ja-JP" };
- var originalUICulture = CultureInfo.CurrentCulture;
- var emtpyObjArray = new object[] { };
-
- // run all the tests, varying the culture each time.
- try
- {
- foreach (var culture in cultures)
- {
- CultureInfo.CurrentCulture = new CultureInfo(culture);
-
- foreach (var c in testClasses)
- {
- var instance = c.Constructor.Invoke(emtpyObjArray);
- if (c.ClassInit != null)
- {
- c.ClassInit.Invoke(instance, emtpyObjArray);
- }
- foreach (var m in c.TestMethods)
- {
- if (c.TestInit != null)
- {
- c.TestInit.Invoke(instance, emtpyObjArray);
- }
- m.Invoke(instance, emtpyObjArray);
- if (c.TestCleanup != null)
- {
- c.TestCleanup.Invoke(instance, emtpyObjArray);
- }
- }
- if (c.ClassCleanup != null)
- {
- c.ClassCleanup.Invoke(instance, emtpyObjArray);
- }
- }
- }
- }
- finally
- {
- CultureInfo.CurrentCulture = originalUICulture;
- }
-
- }
- }
-
- public class NotReRunnableAttribute : Attribute
- {
-
- }
-}
diff --git a/neo.UnitTests/UT_Fixed8.cs b/neo.UnitTests/UT_Fixed8.cs
deleted file mode 100644
index 139bcd158b..0000000000
--- a/neo.UnitTests/UT_Fixed8.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_Fixed8
- {
- [TestMethod]
- public void Basic_equality()
- {
- var a = Fixed8.FromDecimal(1.23456789m);
- var b = Fixed8.Parse("1.23456789");
- a.Should().Be(b);
- }
-
- [TestMethod]
- public void Can_parse_exponent_notation()
- {
- Fixed8 expected = Fixed8.FromDecimal(1.23m);
- Fixed8 actual = Fixed8.Parse("1.23E-0");
- actual.Should().Be(expected);
- }
- }
-}
\ No newline at end of file
diff --git a/neo.UnitTests/UT_Header.cs b/neo.UnitTests/UT_Header.cs
deleted file mode 100644
index a0a508f9d5..0000000000
--- a/neo.UnitTests/UT_Header.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_Header
- {
- Header uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new Header();
- }
-
- [TestMethod]
- public void Size_Get()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- TestUtils.SetupHeaderWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal);
- // blockbase 4 + 32 + 32 + 4 + 4 + 8 + 20 + 1 + 3
- // header 1
- uut.Size.Should().Be(109);
- }
-
- [TestMethod]
- public void Deserialize()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- TestUtils.SetupHeaderWithValues(new Header(), val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal);
-
- uut.MerkleRoot = merkRoot; // need to set for deserialise to be valid
-
- byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 128, 171, 4, 253, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 81, 0 };
- int index = 0;
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- {
- using (BinaryReader reader = new BinaryReader(ms))
- {
- uut.Deserialize(reader);
- }
- }
-
- assertStandardHeaderTestVals(val256, merkRoot, val160, timestampVal, indexVal, consensusDataVal, scriptVal);
- }
-
- private void assertStandardHeaderTestVals(UInt256 val256, UInt256 merkRoot, UInt160 val160, uint timestampVal, uint indexVal, ulong consensusDataVal, Witness scriptVal)
- {
- uut.PrevHash.Should().Be(val256);
- uut.MerkleRoot.Should().Be(merkRoot);
- uut.Timestamp.Should().Be(timestampVal);
- uut.Index.Should().Be(indexVal);
- uut.ConsensusData.Should().Be(consensusDataVal);
- uut.NextConsensus.Should().Be(val160);
- uut.Script.InvocationScript.Length.Should().Be(0);
- uut.Script.Size.Should().Be(scriptVal.Size);
- uut.Script.VerificationScript[0].Should().Be(scriptVal.VerificationScript[0]);
- }
-
- [TestMethod]
- public void Equals_Null()
- {
- uut.Equals(null).Should().BeFalse();
- }
-
-
- [TestMethod]
- public void Equals_SameHeader()
- {
- uut.Equals(uut).Should().BeTrue();
- }
-
- [TestMethod]
- public void Equals_SameHash()
- {
- Header newHeader = new Header();
- UInt256 prevHash = new UInt256(TestUtils.GetByteArray(32, 0x42));
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- TestUtils.SetupHeaderWithValues(newHeader, prevHash, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal);
- TestUtils.SetupHeaderWithValues(uut, prevHash, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal);
-
- uut.Equals(newHeader).Should().BeTrue();
- }
-
- [TestMethod]
- public void Equals_SameObject()
- {
- uut.Equals((object)uut).Should().BeTrue();
- }
-
- [TestMethod]
- public void FromTrimmedData()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRoot;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- TestUtils.SetupHeaderWithValues(new Header(), val256, out merkRoot, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal);
-
- byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 128, 171, 4, 253, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 81, 0 };
-
- uut = Header.FromTrimmedData(data, 0);
-
- assertStandardHeaderTestVals(val256, merkRoot, val160, timestampVal, indexVal, consensusDataVal, scriptVal);
- }
-
- [TestMethod]
- public void Serialize()
- {
- UInt256 val256 = UInt256.Zero;
- UInt256 merkRootVal;
- UInt160 val160;
- uint timestampVal, indexVal;
- ulong consensusDataVal;
- Witness scriptVal;
- TestUtils.SetupHeaderWithValues(uut, val256, out merkRootVal, out val160, out timestampVal, out indexVal, out consensusDataVal, out scriptVal);
-
- byte[] data;
- using (MemoryStream stream = new MemoryStream())
- {
- using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
- {
- uut.Serialize(writer);
- data = stream.ToArray();
- }
- }
-
- byte[] requiredData = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 87, 42, 69, 155, 149, 217, 19, 107, 122, 113, 60, 84, 133, 202, 112, 159, 158, 250, 79, 8, 241, 194, 93, 215, 146, 103, 45, 43, 215, 91, 251, 128, 171, 4, 253, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 81, 0 };
-
- data.Length.Should().Be(109);
- for (int i = 0; i < 109; i++)
- {
- data[i].Should().Be(requiredData[i]);
- }
- }
- }
-}
diff --git a/neo.UnitTests/UT_Helper.cs b/neo.UnitTests/UT_Helper.cs
deleted file mode 100644
index fddcf06318..0000000000
--- a/neo.UnitTests/UT_Helper.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using FluentAssertions;
-using Neo.Core;
-using Neo.Wallets;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_Helper
- {
- [TestMethod]
- public void GetHashData()
- {
- TestVerifiable verifiable = new TestVerifiable();
- byte[] res = verifiable.GetHashData();
- res.Length.Should().Be(8);
- byte[] requiredData = new byte[] {7, 116, 101, 115, 116, 83, 116, 114};
- for (int i = 0; i < requiredData.Length; i++)
- {
- res[i].Should().Be(requiredData[i]);
- }
- }
-
- [TestMethod]
- public void Sign()
- {
- TestVerifiable verifiable = new TestVerifiable();
- byte[] res = verifiable.Sign(new KeyPair(TestUtils.GetByteArray(32,0x42)));
- res.Length.Should().Be(64);
- }
-
- [TestMethod]
- public void ToScriptHash()
- {
- byte[] testByteArray = TestUtils.GetByteArray(64,0x42);
- UInt160 res = testByteArray.ToScriptHash();
- res.Should().Be(UInt160.Parse("2d3b96ae1bcc5a585e075e3b81920210dec16302"));
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_InvocationTransaction.cs b/neo.UnitTests/UT_InvocationTransaction.cs
deleted file mode 100644
index 77b665f92a..0000000000
--- a/neo.UnitTests/UT_InvocationTransaction.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO.Json;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_InvocationTransaction
- {
- InvocationTransaction uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new InvocationTransaction();
- }
-
- [TestMethod]
- public void Script_Get()
- {
- uut.Script.Should().BeNull();
- }
-
- [TestMethod]
- public void Script_Set()
- {
- byte[] val = TestUtils.GetByteArray(32, 0x42);
- uut.Script = val;
- uut.Script.Length.Should().Be(32);
- for (int i = 0; i < val.Length; i++)
- {
- uut.Script[i].Should().Be(val[i]);
- }
- }
-
- [TestMethod]
- public void Gas_Get()
- {
- uut.Gas.Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void Gas_Set()
- {
- Fixed8 val = Fixed8.FromDecimal(42);
- uut.Gas = val;
- uut.Gas.Should().Be(val);
- }
-
- [TestMethod]
- public void Size_Get()
- {
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- byte[] val = TestUtils.GetByteArray(32, 0x42);
- uut.Script = val;
- uut.Size.Should().Be(39); // 1, 1, 1, 1, 1, 1 + script 33
- }
-
- [TestMethod]
- public void SystemFee_Get()
- {
- uut.SystemFee.Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void SystemFee_Get_FromGas()
- {
- Fixed8 val = Fixed8.FromDecimal(42);
- uut.Gas = val;
- uut.SystemFee.Should().Be(val);
- }
-
- [TestMethod]
- public void SystemFee_Set()
- {
- Fixed8 val = Fixed8.FromDecimal(42);
- uut.Gas = val;
- uut.SystemFee.Should().Be(val);
- }
-
- [TestMethod]
- public void ToJson()
- {
- byte[] scriptVal = TestUtils.GetByteArray(32, 0x42);
- uut.Script = scriptVal;
- Fixed8 gasVal = Fixed8.FromDecimal(42);
- uut.Gas = gasVal;
-
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- JObject jObj = uut.ToJson();
- jObj.Should().NotBeNull();
- jObj["txid"].AsString().Should().Be("0x8258b950487299376f89ad2d09598b7acbc5cde89b161b3dd73c256f9e2a94b1");
- jObj["size"].AsNumber().Should().Be(39);
- jObj["type"].AsString().Should().Be("InvocationTransaction");
- jObj["version"].AsNumber().Should().Be(0);
- ((JArray)jObj["attributes"]).Count.Should().Be(0);
- ((JArray)jObj["vin"]).Count.Should().Be(0);
- ((JArray)jObj["vout"]).Count.Should().Be(0);
- jObj["sys_fee"].AsString().Should().Be("42");
- jObj["net_fee"].AsString().Should().Be("-42");
- ((JArray)jObj["scripts"]).Count.Should().Be(0);
-
- jObj["script"].AsString().Should().Be("4220202020202020202020202020202020202020202020202020202020202020");
- jObj["gas"].AsNumber().Should().Be(42);
- }
- }
-}
diff --git a/neo.UnitTests/UT_IssueTransaction.cs b/neo.UnitTests/UT_IssueTransaction.cs
deleted file mode 100644
index efb6ae8580..0000000000
--- a/neo.UnitTests/UT_IssueTransaction.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO.Json;
-using Neo.Wallets;
-using Neo.VM;
-using Neo.SmartContract;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_IssueTransaction
- {
- IssueTransaction uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new IssueTransaction();
- }
-
- [TestMethod]
- public void SystemFee_Get()
- {
- uut.Version = 1;
- uut.SystemFee.Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void SystemFee_Get_Version_0_Share()
- {
- uut = TestUtils.GetIssueTransaction(false, 10, Blockchain.GoverningToken.Hash);
- uut.Version = 0;
-
- uut.SystemFee.Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void SystemFee_Get_Version_0_Coin()
- {
- uut = TestUtils.GetIssueTransaction(false, 10, Blockchain.UtilityToken.Hash);
- uut.Version = 0;
-
- uut.SystemFee.Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void SystemFee_Get_Version_0_OtherAsset()
- {
- uut = TestUtils.GetIssueTransaction(false, 10, new UInt256(TestUtils.GetByteArray(32,0x42)));
- uut.Version = 0;
-
- uut.SystemFee.Should().Be(Fixed8.FromDecimal(500));
- }
-
- [TestMethod]
- public void GetScriptHashesForVerifying()
- {
- TestUtils.SetupTestBlockchain(UInt256.Zero);
- uut = TestUtils.GetIssueTransaction(false, 10, Blockchain.UtilityToken.Hash);
- UInt160[] res = uut.GetScriptHashesForVerifying();
- res.Length.Should().Be(1);
- res[0].Should().Be(new UInt160(TestUtils.GetByteArray(20, 0xe7)));
- }
-
- [TestMethod]
- public void GetScriptHashesForVerifying_ThrowsException_NullAsset()
- {
- TestUtils.SetupTestBlockchain(UInt256.Zero);
- uut = TestUtils.GetIssueTransaction(false, 10, UInt256.Zero);
- Action test = () => uut.GetScriptHashesForVerifying();
- test.ShouldThrow();
- }
-
- [TestMethod]
- public void GetScriptHashesForVerifying_Ordered()
- {
- TestUtils.SetupTestBlockchain(UInt256.Zero);
- uut = new IssueTransaction
- {
- Attributes = new TransactionAttribute[0],
- Inputs = new CoinReference[0],
- Outputs = new[]
- {
- new TransactionOutput
- {
- AssetId = Blockchain.UtilityToken.Hash,
- Value = Fixed8.FromDecimal(10),
- ScriptHash = Contract.CreateMultiSigRedeemScript(1, TestUtils.StandbyValidators).ToScriptHash()
- },
- new TransactionOutput
- {
- AssetId = Blockchain.GoverningToken.Hash,
- Value = Fixed8.FromDecimal(10),
- ScriptHash = Contract.CreateMultiSigRedeemScript(1, TestUtils.StandbyValidators).ToScriptHash()
- },
- },
- Scripts = new[]
- {
- new Witness
- {
- InvocationScript = new byte[0],
- VerificationScript = new[] { (byte)OpCode.PUSHT }
- }
- }
- };
- UInt160[] res = uut.GetScriptHashesForVerifying();
- res.Length.Should().Be(2);
- res[0].Should().Be(new UInt160(TestUtils.GetByteArray(20, 0x9b)));
- res[1].Should().Be(new UInt160(TestUtils.GetByteArray(20, 0xe7)));
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_MinerTransaction.cs b/neo.UnitTests/UT_MinerTransaction.cs
deleted file mode 100644
index 9c6110e6ad..0000000000
--- a/neo.UnitTests/UT_MinerTransaction.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO.Json;
-using Neo.Wallets;
-using Neo.VM;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_MinerTransaction
- {
- MinerTransaction uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new MinerTransaction();
- }
-
- [TestMethod]
- public void Nonce_Get()
- {
- uut.Nonce.Should().Be(0u);
- }
-
- [TestMethod]
- public void Nonce_Set()
- {
- uint val = 42;
- uut.Nonce = val;
- uut.Nonce.Should().Be(val);
- }
-
- [TestMethod]
- public void NetworkFee_Get()
- {
- uut.NetworkFee.Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void Size_Get()
- {
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
-
- uut.Size.Should().Be(10); // 1, 1, 1, 1, 1, 1 + 4
- }
-
- [TestMethod]
- public void ToJson()
- {
- uut.Attributes = new TransactionAttribute[0];
- uut.Inputs = new CoinReference[0];
- uut.Outputs = new TransactionOutput[0];
- uut.Scripts = new Witness[0];
- uut.Nonce = 42;
-
- JObject jObj = uut.ToJson();
- jObj.Should().NotBeNull();
- jObj["txid"].AsString().Should().Be("0xe42ca5744eda6de2e1a2bdc2ed98fa7b967b13cd3aa2605c95fff37261f07ef6");
- jObj["size"].AsNumber().Should().Be(10);
- jObj["type"].AsString().Should().Be("MinerTransaction");
- jObj["version"].AsNumber().Should().Be(0);
- ((JArray)jObj["attributes"]).Count.Should().Be(0);
- ((JArray)jObj["vin"]).Count.Should().Be(0);
- ((JArray)jObj["vout"]).Count.Should().Be(0);
- jObj["sys_fee"].AsNumber().Should().Be(0);
- jObj["net_fee"].AsNumber().Should().Be(0);
- ((JArray)jObj["scripts"]).Count.Should().Be(0);
-
- jObj["nonce"].AsNumber().Should().Be(42);
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_SpentCoint.cs b/neo.UnitTests/UT_SpentCoint.cs
deleted file mode 100644
index 117ceb6d08..0000000000
--- a/neo.UnitTests/UT_SpentCoint.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_SpentCoint
- {
- SpentCoin uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new SpentCoin();
- }
-
- [TestMethod]
- public void Output_Get()
- {
- uut.Output.Should().BeNull();
- }
-
- [TestMethod]
- public void Output_Set()
- {
- TransactionOutput val = new TransactionOutput();
- uut.Output = val;
- uut.Output.Should().Be(val);
- }
-
- [TestMethod]
- public void StartHeight_Get()
- {
- uut.StartHeight.Should().Be(0u);
- }
-
- [TestMethod]
- public void StartHeight_Set()
- {
- uint val = 42;
- uut.StartHeight = val;
- uut.StartHeight.Should().Be(val);
- }
-
- [TestMethod]
- public void EndHeight_Get()
- {
- uut.EndHeight.Should().Be(0u);
- }
-
- [TestMethod]
- public void EndHeight_Set()
- {
- uint val = 42;
- uut.EndHeight = val;
- uut.EndHeight.Should().Be(val);
- }
-
- [TestMethod]
- public void Value_Get()
- {
- TransactionOutput val = new TransactionOutput();
- val.Value = Fixed8.FromDecimal(42);
- uut.Output = val;
- uut.Value.Should().Be(val.Value);
- }
- }
-}
diff --git a/neo.UnitTests/UT_SpentCointState.cs b/neo.UnitTests/UT_SpentCointState.cs
deleted file mode 100644
index c728c4bcf7..0000000000
--- a/neo.UnitTests/UT_SpentCointState.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_SpentCointState
- {
- SpentCoinState uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new SpentCoinState();
- }
-
- [TestMethod]
- public void TransactionHash_Get()
- {
- uut.TransactionHash.Should().BeNull();
- }
-
- [TestMethod]
- public void TransactionHash_Set()
- {
- UInt256 val = new UInt256();
- uut.TransactionHash = val;
- uut.TransactionHash.Should().Be(val);
- }
-
- [TestMethod]
- public void TransactionHeight_Get()
- {
- uut.TransactionHeight.Should().Be(0u);
- }
-
- [TestMethod]
- public void TransactionHeight_Set()
- {
- uint val = 4294967295;
- uut.TransactionHeight = val;
- uut.TransactionHeight.Should().Be(val);
- }
-
- [TestMethod]
- public void Items_Get()
- {
- uut.Items.Should().BeNull();
- }
-
- [TestMethod]
- public void Items_Set()
- {
- ushort key = new ushort();
- uint val = new uint();
- Dictionary dict = new Dictionary();
- dict.Add(key, val);
- uut.Items = dict;
- uut.Items[key].Should().Be(val);
- }
-
- [TestMethod]
- public void Size_Get_With_No_Items()
- {
- UInt256 val = new UInt256();
- Dictionary dict = new Dictionary();
- uut.TransactionHash = val;
- uut.Items = dict;
- uut.Size.Should().Be(38); // 1 + 32 + 4 + 1 + 0 * (2 + 4)
- }
-
- [TestMethod]
- public void Size_Get_With_Items()
- {
- UInt256 val = new UInt256();
- Dictionary dict = new Dictionary();
- uut.TransactionHash = val;
- dict.Add(42, 100);
- uut.Items = dict;
- uut.Size.Should().Be(44); // 1 + 32 + 4 + 1 + 1 * (2 + 4)
- }
-
- private void setupSpentCoinStateWithValues(SpentCoinState spentCoinState, out UInt256 transactionHash, out uint transactionHeight)
- {
- transactionHash = new UInt256(TestUtils.GetByteArray(32, 0x20));
- spentCoinState.TransactionHash = transactionHash;
- transactionHeight = 757859114;
- spentCoinState.TransactionHeight = transactionHeight;
- Dictionary dict = new Dictionary();
- dict.Add(42, 100);
- spentCoinState.Items = dict;
- }
-
- [TestMethod]
- public void DeserializeSCS()
- {
- byte[] dataArray = new byte[] { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 42, 3, 44, 45, 1, 42, 0, 0, 0, 0, 0 };
-
- using (Stream stream = new MemoryStream(dataArray))
- {
- using (BinaryReader reader = new BinaryReader(stream))
- {
- uut.Deserialize(reader);
- }
- }
- uut.TransactionHash.Should().Be(new UInt256(TestUtils.GetByteArray(32, 0x20)));
- uut.TransactionHeight.Should().Be(757859114);
- uut.Items.Should().ContainKey(42);
- uut.Items[42].Should().Be(0);
- }
-
- [TestMethod]
- public void SerializeSCS()
- {
- UInt256 transactionHash;
- uint transactionHeight;
- setupSpentCoinStateWithValues(uut, out transactionHash, out transactionHeight);
-
- byte[] dataArray;
- using (MemoryStream stream = new MemoryStream())
- {
- using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
- {
- uut.Serialize(writer);
- dataArray = stream.ToArray();
- }
- }
- byte[] requiredData = new byte[] { 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 42, 3, 44, 45, 1, 42, 0, 100, 0, 0, 0 };
- dataArray.Length.Should().Be(44);
- for (int i = 0; i < 44; i++)
- {
- dataArray[i].Should().Be(requiredData[i]);
- }
- }
- }
-}
diff --git a/neo.UnitTests/UT_StorageItem.cs b/neo.UnitTests/UT_StorageItem.cs
deleted file mode 100644
index ec36b90762..0000000000
--- a/neo.UnitTests/UT_StorageItem.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_StorageItem
- {
- StorageItem uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new StorageItem();
- }
-
- [TestMethod]
- public void Value_Get()
- {
- uut.Value.Should().BeNull();
- }
-
- [TestMethod]
- public void Value_Set()
- {
- byte[] val = new byte[] { 0x42, 0x32};
- uut.Value = val;
- uut.Value.Length.Should().Be(2);
- uut.Value[0].Should().Be(val[0]);
- uut.Value[1].Should().Be(val[1]);
- }
-
- [TestMethod]
- public void Size_Get()
- {
- uut.Value = TestUtils.GetByteArray(10, 0x42);
- uut.Size.Should().Be(12); // 2 + 10
- }
-
- [TestMethod]
- public void Size_Get_Larger()
- {
- uut.Value = TestUtils.GetByteArray(88, 0x42);
- uut.Size.Should().Be(90); // 2 + 88
- }
-
- [TestMethod]
- public void Clone()
- {
- uut.Value = TestUtils.GetByteArray(10, 0x42);
-
- StorageItem newSi = ((ICloneable)uut).Clone();
- newSi.Value.Length.Should().Be(10);
- newSi.Value[0].Should().Be(0x42);
- for (int i=1; i<10; i++)
- {
- newSi.Value[i].Should().Be(0x20);
- }
- }
-
- [TestMethod]
- public void Deserialize()
- {
- byte[] data = new byte[] { 0, 10, 66, 32, 32, 32, 32, 32, 32, 32, 32, 32 };
- int index = 0;
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- {
- using (BinaryReader reader = new BinaryReader(ms))
- {
- uut.Deserialize(reader);
- }
- }
- uut.Value.Length.Should().Be(10);
- uut.Value[0].Should().Be(0x42);
- for (int i = 1; i < 10; i++)
- {
- uut.Value[i].Should().Be(0x20);
- }
- }
-
- [TestMethod]
- public void Serialize()
- {
- uut.Value = TestUtils.GetByteArray(10, 0x42);
-
- byte[] data;
- using (MemoryStream stream = new MemoryStream())
- {
- using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
- {
- uut.Serialize(writer);
- data = stream.ToArray();
- }
- }
-
- byte[] requiredData = new byte[] { 0, 10, 66, 32, 32, 32, 32, 32, 32, 32, 32, 32 };
-
- data.Length.Should().Be(12);
- for (int i = 0; i < 12; i++)
- {
- data[i].Should().Be(requiredData[i]);
- }
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_StorageKey.cs b/neo.UnitTests/UT_StorageKey.cs
deleted file mode 100644
index 037e0c3309..0000000000
--- a/neo.UnitTests/UT_StorageKey.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_StorageKey
- {
- StorageKey uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new StorageKey();
- }
-
- [TestMethod]
- public void ScriptHash_Get()
- {
- uut.ScriptHash.Should().BeNull();
- }
-
- [TestMethod]
- public void ScriptHash_Set()
- {
- UInt160 val = new UInt160(TestUtils.GetByteArray(20, 0x42));
- uut.ScriptHash = val;
- uut.ScriptHash.Should().Be(val);
- }
-
- [TestMethod]
- public void Key_Get()
- {
- uut.Key.Should().BeNull();
- }
-
- [TestMethod]
- public void Key_Set()
- {
- byte[] val = new byte[] { 0x42, 0x32 };
- uut.Key = val;
- uut.Key.Length.Should().Be(2);
- uut.Key[0].Should().Be(val[0]);
- uut.Key[1].Should().Be(val[1]);
- }
-
- [TestMethod]
- public void Equals_SameObj()
- {
- uut.Equals(uut).Should().BeTrue();
- }
-
- [TestMethod]
- public void Equals_Null()
- {
- uut.Equals(null).Should().BeFalse();
- }
-
- [TestMethod]
- public void Equals_SameHash_SameKey()
- {
- UInt160 val = new UInt160(TestUtils.GetByteArray(20, 0x42));
- byte[] keyVal = TestUtils.GetByteArray(10, 0x42);
- StorageKey newSk = new StorageKey();
- newSk.ScriptHash = val;
- newSk.Key = keyVal;
- uut.ScriptHash = val;
- uut.Key = keyVal;
-
- uut.Equals(newSk).Should().BeTrue();
- }
-
- [TestMethod]
- public void Equals_DiffHash_SameKey()
- {
- UInt160 val = new UInt160(TestUtils.GetByteArray(20, 0x42));
- byte[] keyVal = TestUtils.GetByteArray(10, 0x42);
- StorageKey newSk = new StorageKey();
- newSk.ScriptHash = val;
- newSk.Key = keyVal;
- uut.ScriptHash = new UInt160(TestUtils.GetByteArray(20, 0x88));
- uut.Key = keyVal;
-
- uut.Equals(newSk).Should().BeFalse();
- }
-
-
- [TestMethod]
- public void Equals_SameHash_DiffKey()
- {
- UInt160 val = new UInt160(TestUtils.GetByteArray(20, 0x42));
- byte[] keyVal = TestUtils.GetByteArray(10, 0x42);
- StorageKey newSk = new StorageKey();
- newSk.ScriptHash = val;
- newSk.Key = keyVal;
- uut.ScriptHash = val;
- uut.Key = TestUtils.GetByteArray(10, 0x88);
-
- uut.Equals(newSk).Should().BeFalse();
- }
-
- [TestMethod]
- public void GetHashCode_Get()
- {
- uut.ScriptHash = new UInt160(TestUtils.GetByteArray(20, 0x42));
- uut.Key = TestUtils.GetByteArray(10, 0x42);
- uut.GetHashCode().Should().Be(806209853);
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_TransactionAttribute.cs b/neo.UnitTests/UT_TransactionAttribute.cs
deleted file mode 100644
index c5ff05c7b4..0000000000
--- a/neo.UnitTests/UT_TransactionAttribute.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO.Json;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_TransactionAttribute
- {
- TransactionAttribute uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new TransactionAttribute();
- }
-
- [TestMethod]
- public void Usage_Get()
- {
- uut.Usage.Should().Be(TransactionAttributeUsage.ContractHash);
- }
-
- [TestMethod]
- public void Usage_Set()
- {
- uut.Usage = TransactionAttributeUsage.ECDH02;
- uut.Usage.Should().Be(TransactionAttributeUsage.ECDH02);
- }
-
- [TestMethod]
- public void Data_Get()
- {
- uut.Data.Should().BeNull();
- }
-
- [TestMethod]
- public void Data_Set()
- {
- byte[] val = new byte[] { 0x42, 0x32 };
- uut.Data = val;
- uut.Data.Length.Should().Be(2);
- uut.Data[0].Should().Be(val[0]);
- uut.Data[1].Should().Be(val[1]);
- }
-
- [TestMethod]
- public void Size_Get_ContractHash()
- {
- uut.Usage = TransactionAttributeUsage.ContractHash;
- uut.Size.Should().Be(33); // 1 + 32
- }
-
- [TestMethod]
- public void Size_Get_ECDH02()
- {
- uut.Usage = TransactionAttributeUsage.ECDH02;
- uut.Size.Should().Be(33); // 1 + 32
- }
-
- [TestMethod]
- public void Size_Get_ECDH03()
- {
- uut.Usage = TransactionAttributeUsage.ECDH03;
- uut.Size.Should().Be(33); // 1 + 32
- }
-
- [TestMethod]
- public void Size_Get_Vote()
- {
- uut.Usage = TransactionAttributeUsage.Vote;
- uut.Size.Should().Be(33); // 1 + 32
- }
-
- [TestMethod]
- public void Size_Get_Hash()
- {
- for (TransactionAttributeUsage i = TransactionAttributeUsage.Hash1; i <= TransactionAttributeUsage.Hash15; i++)
- {
- uut.Usage = i;
- uut.Size.Should().Be(33); // 1 + 32
- }
- }
-
- [TestMethod]
- public void Size_Get_Script()
- {
- uut.Usage = TransactionAttributeUsage.Script;
- uut.Size.Should().Be(21); // 1 + 20
- }
-
- [TestMethod]
- public void Size_Get_DescriptionUrl()
- {
- uut.Usage = TransactionAttributeUsage.DescriptionUrl;
- uut.Data = TestUtils.GetByteArray(10, 0x42);
- uut.Size.Should().Be(12); // 1 + 1 + 10
- }
-
- [TestMethod]
- public void Size_Get_OtherAttribute()
- {
- uut.Usage = TransactionAttributeUsage.Remark;
- uut.Data = TestUtils.GetByteArray(10, 0x42);
- uut.Size.Should().Be(12); // 1 + 11
- }
-
- [TestMethod]
- public void ToJson()
- {
- uut.Usage = TransactionAttributeUsage.ECDH02;
- uut.Data = TestUtils.GetByteArray(10, 0x42);
-
- JObject jObj = uut.ToJson();
- jObj.Should().NotBeNull();
- jObj["usage"].AsString().Should().Be("ECDH02");
- jObj["data"].AsString().Should().Be("42202020202020202020");
- }
- }
-}
diff --git a/neo.UnitTests/UT_TransactionOutput.cs b/neo.UnitTests/UT_TransactionOutput.cs
deleted file mode 100644
index 20862110e7..0000000000
--- a/neo.UnitTests/UT_TransactionOutput.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO.Json;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_TransactionOutput
- {
- TransactionOutput uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new TransactionOutput();
- }
-
- [TestMethod]
- public void AssetId_Get()
- {
- uut.AssetId.Should().BeNull();
- }
-
- [TestMethod]
- public void AssetId_Set()
- {
- UInt256 val = new UInt256(TestUtils.GetByteArray(32, 0x42));
- uut.AssetId = val;
- uut.AssetId.Should().Be(val);
- }
-
- [TestMethod]
- public void Value_Get()
- {
- uut.Value.Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void Value_Set()
- {
- Fixed8 val = Fixed8.FromDecimal(42);
- uut.Value = val;
- uut.Value.Should().Be(val);
- }
-
- [TestMethod]
- public void ScriptHash_Get()
- {
- uut.ScriptHash.Should().BeNull();
- }
-
- [TestMethod]
- public void ScriptHash_Set()
- {
- UInt160 val = new UInt160(TestUtils.GetByteArray(20, 0x42));
- uut.ScriptHash = val;
- uut.ScriptHash.Should().Be(val);
- }
-
- [TestMethod]
- public void Size_Get()
- {
- uut.AssetId = new UInt256(TestUtils.GetByteArray(32, 0x42));
- uut.Value = Fixed8.FromDecimal(42);
- uut.ScriptHash = new UInt160(TestUtils.GetByteArray(20, 0x42));
-
- uut.Size.Should().Be(60); // 32 + 8 + 20
- }
-
- [TestMethod]
- public void ToJson()
- {
- uut.AssetId = new UInt256(TestUtils.GetByteArray(32, 0x42));
- uut.Value = Fixed8.FromDecimal(42);
- uut.ScriptHash = new UInt160(TestUtils.GetByteArray(20, 0x42));
-
- JObject jObj = uut.ToJson(36);
- jObj.Should().NotBeNull();
- jObj["n"].AsNumber().Should().Be(36);
- jObj["asset"].AsString().Should().Be("0x2020202020202020202020202020202020202020202020202020202020202042");
- jObj["value"].AsString().Should().Be("42");
- jObj["address"].AsString().Should().Be("AMoWjH3BDwMY7j8FEAovPJdq8XEuyJynwN");
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_TransactionResult.cs b/neo.UnitTests/UT_TransactionResult.cs
deleted file mode 100644
index da6165807e..0000000000
--- a/neo.UnitTests/UT_TransactionResult.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO.Json;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_TransactionResult
- {
- TransactionResult uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new TransactionResult();
- }
-
- [TestMethod]
- public void AssetId_Get()
- {
- uut.AssetId.Should().BeNull();
- }
-
- [TestMethod]
- public void AssetId_Set()
- {
- UInt256 val = new UInt256(TestUtils.GetByteArray(32, 0x42));
- uut.AssetId = val;
- uut.AssetId.Should().Be(val);
- }
-
- [TestMethod]
- public void Amount_Get()
- {
- uut.Amount.Should().Be(Fixed8.Zero);
- }
-
- [TestMethod]
- public void Amount_Set()
- {
- Fixed8 val = Fixed8.FromDecimal(42);
- uut.Amount = val;
- uut.Amount.Should().Be(val);
- }
- }
-}
diff --git a/neo.UnitTests/UT_UnspentCoinState.cs b/neo.UnitTests/UT_UnspentCoinState.cs
deleted file mode 100644
index e8a723808b..0000000000
--- a/neo.UnitTests/UT_UnspentCoinState.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_UnspentCoinState
- {
- UnspentCoinState uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new UnspentCoinState();
- }
-
- [TestMethod]
- public void Items_Get()
- {
- uut.Items.Should().BeNull();
- }
-
- [TestMethod]
- public void Items_Set()
- {
- CoinState item1 = CoinState.Confirmed;
- CoinState item2 = CoinState.Spent;
- CoinState[] val = new CoinState[] { item1, item2 };
- uut.Items = val;
- uut.Items.Length.Should().Be(val.Length);
- uut.Items[0].Should().Be(item1);
- uut.Items[1].Should().Be(item2);
- }
-
- [TestMethod]
- public void Size_Get_1()
- {
- CoinState item1 = CoinState.Confirmed;
- CoinState[] val = new CoinState[] { item1 };
- uut.Items = val;
-
- uut.Size.Should().Be(3); // 1 + 2
- }
-
- [TestMethod]
- public void Size_Get_3()
- {
- CoinState item1 = CoinState.Confirmed;
- CoinState item2 = CoinState.Frozen;
- CoinState item3 = CoinState.Spent;
- CoinState[] val = new CoinState[] { item1, item2, item3 };
- uut.Items = val;
-
- uut.Size.Should().Be(5); // 1 + 4
- }
-
- [TestMethod]
- public void Deserialize()
- {
- byte[] data = new byte[] { 0, 2, 1, 8 };
- int index = 0;
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- {
- using (BinaryReader reader = new BinaryReader(ms))
- {
- uut.Deserialize(reader);
- }
- }
- uut.Items.Length.Should().Be(2);
- uut.Items[0].Should().Be(CoinState.Confirmed);
- uut.Items[1].Should().Be(CoinState.Claimed);
- }
-
- [TestMethod]
- public void Serialize()
- {
- CoinState item1 = CoinState.Confirmed;
- CoinState item2 = CoinState.Claimed;
- CoinState[] val = new CoinState[] { item1, item2 };
- uut.Items = val;
-
- byte[] data;
- using (MemoryStream stream = new MemoryStream())
- {
- using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
- {
- uut.Serialize(writer);
- data = stream.ToArray();
- }
- }
-
- byte[] requiredData = new byte[] { 0, 2, 1, 8 };
-
- data.Length.Should().Be(requiredData.Length);
- for (int i = 0; i < requiredData.Length; i++)
- {
- data[i].Should().Be(requiredData[i]);
- }
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_ValidatorState.cs b/neo.UnitTests/UT_ValidatorState.cs
deleted file mode 100644
index 1c393bc756..0000000000
--- a/neo.UnitTests/UT_ValidatorState.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.Cryptography.ECC;
-using System.IO;
-using System.Text;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_ValidatorState
- {
- ValidatorState uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new ValidatorState();
- }
-
- [TestMethod]
- public void PublicKey_Get()
- {
- uut.PublicKey.Should().BeNull();
- }
-
- [TestMethod]
- public void Items_Set()
- {
- ECPoint val = new ECPoint();
- uut.PublicKey = val;
- uut.PublicKey.Should().Be(val);
- }
-
- [TestMethod]
- public void Size_Get()
- {
- ECPoint val = ECPoint.DecodePoint("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c".HexToBytes(), ECCurve.Secp256r1);
- uut.PublicKey = val;
-
- uut.Size.Should().Be(43); // 1 + 33 + 1 + 8
- }
-
- [TestMethod]
- public void Deserialize()
- {
- byte[] data = new byte[] { 0, 3, 178, 9, 253, 79, 83, 167, 23, 14, 164, 68, 78, 12, 176, 166, 187, 106, 83, 194, 189, 1, 105, 38, 152, 156, 248, 95, 155, 15, 186, 23, 167, 12, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
- int index = 0;
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- {
- using (BinaryReader reader = new BinaryReader(ms))
- {
- uut.Deserialize(reader);
- }
- }
- uut.PublicKey.ToString().Should().Be("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c");
- }
-
- [TestMethod]
- public void Equals_SameObj()
- {
- uut.Equals(uut).Should().BeTrue();
- }
-
- [TestMethod]
- public void Equals_DifferentKey()
- {
- ValidatorState newVs = new ValidatorState();
- newVs.PublicKey = ECPoint.DecodePoint("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70b".HexToBytes(), ECCurve.Secp256r1);
- uut.PublicKey = ECPoint.DecodePoint("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c".HexToBytes(), ECCurve.Secp256r1);
- uut.Equals(newVs).Should().BeFalse();
- }
-
- [TestMethod]
- public void Equals_Null()
- {
- uut.Equals(null).Should().BeFalse();
- }
-
- [TestMethod]
- public void Serialize()
- {
- ECPoint val = ECPoint.DecodePoint("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c".HexToBytes(), ECCurve.Secp256r1);
- uut.PublicKey = val;
- uut.Registered = true;
- uut.Votes = Fixed8.Zero;
-
- byte[] data;
- using (MemoryStream stream = new MemoryStream())
- {
- using (BinaryWriter writer = new BinaryWriter(stream, Encoding.ASCII, true))
- {
- uut.Serialize(writer);
- data = stream.ToArray();
- }
- }
-
- byte[] requiredData = new byte[] { 0, 3, 178, 9, 253, 79, 83, 167, 23, 14, 164, 68, 78, 12, 176, 166, 187, 106, 83, 194, 189, 1, 105, 38, 152, 156, 248, 95, 155, 15, 186, 23, 167, 12, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- data.Length.Should().Be(requiredData.Length);
- for (int i = 0; i < requiredData.Length; i++)
- {
- data[i].Should().Be(requiredData[i]);
- }
- }
-
- }
-}
diff --git a/neo.UnitTests/UT_Witness.cs b/neo.UnitTests/UT_Witness.cs
deleted file mode 100644
index 48708da55d..0000000000
--- a/neo.UnitTests/UT_Witness.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using FluentAssertions;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Neo.Core;
-using Neo.IO.Json;
-
-namespace Neo.UnitTests
-{
- [TestClass]
- public class UT_Witness
- {
- Witness uut;
-
- [TestInitialize]
- public void TestSetup()
- {
- uut = new Witness();
- }
-
- [TestMethod]
- public void InvocationScript_Get()
- {
- uut.InvocationScript.Should().BeNull();
- }
-
- [TestMethod]
- public void InvocationScript_Set()
- {
- byte[] dataArray = new byte[] { 0, 32, 32, 20, 32, 32 };
- uut.InvocationScript = dataArray;
- uut.InvocationScript.Length.Should().Be(6);
- Assert.AreEqual(uut.InvocationScript.ToHexString(), "002020142020");
- }
-
- private void setupWitnessWithValues(Witness uut, int lenghtInvocation, int lengthVerification, out byte[] invocationScript, out byte[] verificationScript)
- {
- invocationScript = TestUtils.GetByteArray(lenghtInvocation, 0x20);
- verificationScript = TestUtils.GetByteArray(lengthVerification, 0x20);
- uut.InvocationScript = invocationScript;
- uut.VerificationScript = verificationScript;
- }
-
- [TestMethod]
- public void SizeWitness_Small_Arrary()
- {
- byte[] invocationScript;
- byte[] verificationScript;
- setupWitnessWithValues(uut, 252, 253, out invocationScript, out verificationScript);
-
- uut.Size.Should().Be(509); // (1 + 252*1) + (1 + 2 + 253*1)
- }
-
- [TestMethod]
- public void SizeWitness_Large_Arrary()
- {
- byte[] invocationScript;
- byte[] verificationScript;
- setupWitnessWithValues(uut, 65535, 65536, out invocationScript, out verificationScript);
-
- uut.Size.Should().Be(131079); // (1 + 2 + 65535*1) + (1 + 4 + 65536*1)
- }
-
- [TestMethod]
- public void ToJson()
- {
- byte[] invocationScript;
- byte[] verificationScript;
- setupWitnessWithValues(uut, 2, 3, out invocationScript, out verificationScript);
-
- JObject json = uut.ToJson();
- Assert.IsTrue(json.ContainsProperty("invocation"));
- Assert.IsTrue(json.ContainsProperty("verification"));
- Assert.AreEqual(json["invocation"].AsString(), "2020");
- Assert.AreEqual(json["verification"].AsString(), "202020");
-
- }
- }
-}
\ No newline at end of file
diff --git a/neo.UnitTests/neo.UnitTests.csproj b/neo.UnitTests/neo.UnitTests.csproj
deleted file mode 100644
index 87e51b9ce8..0000000000
--- a/neo.UnitTests/neo.UnitTests.csproj
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
- Exe
- netcoreapp2.0
- Neo.UnitTests
- Neo.UnitTests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/neo.png b/neo.png
new file mode 100644
index 0000000000..1a71de07eb
Binary files /dev/null and b/neo.png differ
diff --git a/neo.sln b/neo.sln
index 9d4c436c0e..b4d7ecd8d0 100644
--- a/neo.sln
+++ b/neo.sln
@@ -1,11 +1,33 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26430.15
+# Visual Studio Version 18
+VisualStudioVersion = 18.0.11201.2
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "neo", "neo\neo.csproj", "{36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo", "src\Neo\Neo.csproj", "{36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "neo.UnitTests", "neo.UnitTests\neo.UnitTests.csproj", "{5B783B30-B422-4C2F-AC22-187A8D1993F4}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Json", "src\Neo.Json\Neo.Json.csproj", "{6B709ED6-64C0-451D-B07F-8F49185AE191}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.UnitTests", "tests\Neo.UnitTests\Neo.UnitTests.csproj", "{5B783B30-B422-4C2F-AC22-187A8D1993F4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Json.UnitTests", "tests\Neo.Json.UnitTests\Neo.Json.UnitTests.csproj", "{AE6C32EE-8447-4E01-8187-2AE02BB64251}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Benchmarks", "benchmarks\Neo.Benchmarks\Neo.Benchmarks.csproj", "{BCD03521-5F8F-4775-9ADF-FA361480804F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B5339DF7-5D1D-43BA-B332-74B825E1770E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{EDE05FA8-8E73-4924-BC63-DD117127EEE1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{C25EB0B0-0CAC-4CC1-8F36-F9229EFB99EC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.IO", "src\Neo.IO\Neo.IO.csproj", "{4CDAC1AA-45C6-4157-8D8E-199050433048}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo.Extensions", "src\Neo.Extensions\Neo.Extensions.csproj", "{9C5213D6-3833-4570-8AE2-47E9F9017A8F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Extensions.Tests", "tests\Neo.Extensions.Tests\Neo.Extensions.Tests.csproj", "{77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Extensions.Benchmarks", "benchmarks\Neo.Extensions.Benchmarks\Neo.Extensions.Benchmarks.csproj", "{B6CB2559-10F9-41AC-8D58-364BFEF9688B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo.Json.Benchmarks", "benchmarks\Neo.Json.Benchmarks\Neo.Json.Benchmarks.csproj", "{5F984D2B-793F-4683-B53A-80050E6E0286}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -17,12 +39,59 @@ Global
{36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{36447A9B-0311-4D4D-A3D5-AECBE9C15BBC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6B709ED6-64C0-451D-B07F-8F49185AE191}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6B709ED6-64C0-451D-B07F-8F49185AE191}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6B709ED6-64C0-451D-B07F-8F49185AE191}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6B709ED6-64C0-451D-B07F-8F49185AE191}.Release|Any CPU.Build.0 = Release|Any CPU
{5B783B30-B422-4C2F-AC22-187A8D1993F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5B783B30-B422-4C2F-AC22-187A8D1993F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5B783B30-B422-4C2F-AC22-187A8D1993F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B783B30-B422-4C2F-AC22-187A8D1993F4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AE6C32EE-8447-4E01-8187-2AE02BB64251}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BCD03521-5F8F-4775-9ADF-FA361480804F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BCD03521-5F8F-4775-9ADF-FA361480804F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BCD03521-5F8F-4775-9ADF-FA361480804F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4CDAC1AA-45C6-4157-8D8E-199050433048}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4CDAC1AA-45C6-4157-8D8E-199050433048}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6CB2559-10F9-41AC-8D58-364BFEF9688B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5F984D2B-793F-4683-B53A-80050E6E0286}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5F984D2B-793F-4683-B53A-80050E6E0286}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5F984D2B-793F-4683-B53A-80050E6E0286}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5F984D2B-793F-4683-B53A-80050E6E0286}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {36447A9B-0311-4D4D-A3D5-AECBE9C15BBC} = {B5339DF7-5D1D-43BA-B332-74B825E1770E}
+ {6B709ED6-64C0-451D-B07F-8F49185AE191} = {B5339DF7-5D1D-43BA-B332-74B825E1770E}
+ {5B783B30-B422-4C2F-AC22-187A8D1993F4} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
+ {AE6C32EE-8447-4E01-8187-2AE02BB64251} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
+ {BCD03521-5F8F-4775-9ADF-FA361480804F} = {C25EB0B0-0CAC-4CC1-8F36-F9229EFB99EC}
+ {4CDAC1AA-45C6-4157-8D8E-199050433048} = {B5339DF7-5D1D-43BA-B332-74B825E1770E}
+ {9C5213D6-3833-4570-8AE2-47E9F9017A8F} = {B5339DF7-5D1D-43BA-B332-74B825E1770E}
+ {77FDEE2E-9381-4BFC-B9E6-741EDBD6B90F} = {EDE05FA8-8E73-4924-BC63-DD117127EEE1}
+ {B6CB2559-10F9-41AC-8D58-364BFEF9688B} = {C25EB0B0-0CAC-4CC1-8F36-F9229EFB99EC}
+ {5F984D2B-793F-4683-B53A-80050E6E0286} = {C25EB0B0-0CAC-4CC1-8F36-F9229EFB99EC}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {BCBA19D9-F868-4C6D-8061-A2B91E06E3EC}
+ EndGlobalSection
EndGlobal
diff --git a/neo/BigDecimal.cs b/neo/BigDecimal.cs
deleted file mode 100644
index aefe996425..0000000000
--- a/neo/BigDecimal.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-using System;
-using System.Numerics;
-
-namespace Neo
-{
- public struct BigDecimal
- {
- private readonly BigInteger value;
- private readonly byte decimals;
-
- public BigInteger Value => value;
- public byte Decimals => decimals;
- public int Sign => value.Sign;
-
- public BigDecimal(BigInteger value, byte decimals)
- {
- this.value = value;
- this.decimals = decimals;
- }
-
- public BigDecimal ChangeDecimals(byte decimals)
- {
- if (this.decimals == decimals) return this;
- BigInteger value;
- if (this.decimals < decimals)
- {
- value = this.value * BigInteger.Pow(10, decimals - this.decimals);
- }
- else
- {
- BigInteger divisor = BigInteger.Pow(10, this.decimals - decimals);
- value = BigInteger.DivRem(this.value, divisor, out BigInteger remainder);
- if (remainder > BigInteger.Zero)
- throw new ArgumentOutOfRangeException();
- }
- return new BigDecimal(value, decimals);
- }
-
- public static BigDecimal Parse(string s, byte decimals)
- {
- if (!TryParse(s, decimals, out BigDecimal result))
- throw new FormatException();
- return result;
- }
-
- public Fixed8 ToFixed8()
- {
- try
- {
- return new Fixed8((long)ChangeDecimals(8).value);
- }
- catch (Exception ex)
- {
- throw new InvalidCastException(ex.Message, ex);
- }
- }
-
- public override string ToString()
- {
- BigInteger divisor = BigInteger.Pow(10, decimals);
- BigInteger result = BigInteger.DivRem(value, divisor, out BigInteger remainder);
- if (remainder == 0) return result.ToString();
- return $"{result}.{remainder.ToString("d" + decimals)}".TrimEnd('0');
- }
-
- public static bool TryParse(string s, byte decimals, out BigDecimal result)
- {
- int e = 0;
- int index = s.IndexOfAny(new[] { 'e', 'E' });
- if (index >= 0)
- {
- if (!sbyte.TryParse(s.Substring(index + 1), out sbyte e_temp))
- {
- result = default(BigDecimal);
- return false;
- }
- e = e_temp;
- s = s.Substring(0, index);
- }
- index = s.IndexOf('.');
- if (index >= 0)
- {
- s = s.TrimEnd('0');
- e -= s.Length - index - 1;
- s = s.Remove(index, 1);
- }
- int ds = e + decimals;
- if (ds < 0)
- {
- result = default(BigDecimal);
- return false;
- }
- if (ds > 0)
- s += new string('0', ds);
- if (!BigInteger.TryParse(s, out BigInteger value))
- {
- result = default(BigDecimal);
- return false;
- }
- result = new BigDecimal(value, decimals);
- return true;
- }
- }
-}
diff --git a/neo/Consensus/ChangeView.cs b/neo/Consensus/ChangeView.cs
deleted file mode 100644
index a76979f1ba..0000000000
--- a/neo/Consensus/ChangeView.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.IO;
-
-namespace Neo.Consensus
-{
- internal class ChangeView : ConsensusMessage
- {
- public byte NewViewNumber;
-
- public ChangeView()
- : base(ConsensusMessageType.ChangeView)
- {
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- NewViewNumber = reader.ReadByte();
- if (NewViewNumber == 0) throw new FormatException();
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(NewViewNumber);
- }
- }
-}
diff --git a/neo/Consensus/ConsensusContext.cs b/neo/Consensus/ConsensusContext.cs
deleted file mode 100644
index 417f3aa54e..0000000000
--- a/neo/Consensus/ConsensusContext.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-using Neo.Core;
-using Neo.Cryptography;
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using Neo.Network.Payloads;
-using Neo.Wallets;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Neo.Consensus
-{
- internal class ConsensusContext
- {
- public const uint Version = 0;
- public ConsensusState State;
- public UInt256 PrevHash;
- public uint BlockIndex;
- public byte ViewNumber;
- public ECPoint[] Validators;
- public int MyIndex;
- public uint PrimaryIndex;
- public uint Timestamp;
- public ulong Nonce;
- public UInt160 NextConsensus;
- public UInt256[] TransactionHashes;
- public Dictionary Transactions;
- public byte[][] Signatures;
- public byte[] ExpectedView;
- public KeyPair KeyPair;
-
- public int M => Validators.Length - (Validators.Length - 1) / 3;
-
- public void ChangeView(byte view_number)
- {
- int p = ((int)BlockIndex - view_number) % Validators.Length;
- State &= ConsensusState.SignatureSent;
- ViewNumber = view_number;
- PrimaryIndex = p >= 0 ? (uint)p : (uint)(p + Validators.Length);
- if (State == ConsensusState.Initial)
- {
- TransactionHashes = null;
- Signatures = new byte[Validators.Length][];
- }
- _header = null;
- }
-
- public ConsensusPayload MakeChangeView()
- {
- return MakePayload(new ChangeView
- {
- NewViewNumber = ExpectedView[MyIndex]
- });
- }
-
- private Block _header = null;
- public Block MakeHeader()
- {
- if (TransactionHashes == null) return null;
- if (_header == null)
- {
- _header = new Block
- {
- Version = Version,
- PrevHash = PrevHash,
- MerkleRoot = MerkleTree.ComputeRoot(TransactionHashes),
- Timestamp = Timestamp,
- Index = BlockIndex,
- ConsensusData = Nonce,
- NextConsensus = NextConsensus,
- Transactions = new Transaction[0]
- };
- }
- return _header;
- }
-
- private ConsensusPayload MakePayload(ConsensusMessage message)
- {
- message.ViewNumber = ViewNumber;
- return new ConsensusPayload
- {
- Version = Version,
- PrevHash = PrevHash,
- BlockIndex = BlockIndex,
- ValidatorIndex = (ushort)MyIndex,
- Timestamp = Timestamp,
- Data = message.ToArray()
- };
- }
-
- public ConsensusPayload MakePrepareRequest()
- {
- return MakePayload(new PrepareRequest
- {
- Nonce = Nonce,
- NextConsensus = NextConsensus,
- TransactionHashes = TransactionHashes,
- MinerTransaction = (MinerTransaction)Transactions[TransactionHashes[0]],
- Signature = Signatures[MyIndex]
- });
- }
-
- public ConsensusPayload MakePrepareResponse(byte[] signature)
- {
- return MakePayload(new PrepareResponse
- {
- Signature = signature
- });
- }
-
- public void Reset(Wallet wallet)
- {
- State = ConsensusState.Initial;
- PrevHash = Blockchain.Default.CurrentBlockHash;
- BlockIndex = Blockchain.Default.Height + 1;
- ViewNumber = 0;
- Validators = Blockchain.Default.GetValidators();
- MyIndex = -1;
- PrimaryIndex = BlockIndex % (uint)Validators.Length;
- TransactionHashes = null;
- Signatures = new byte[Validators.Length][];
- ExpectedView = new byte[Validators.Length];
- KeyPair = null;
- for (int i = 0; i < Validators.Length; i++)
- {
- WalletAccount account = wallet.GetAccount(Validators[i]);
- if (account?.HasKey == true)
- {
- MyIndex = i;
- KeyPair = account.GetKey();
- break;
- }
- }
- _header = null;
- }
- }
-}
diff --git a/neo/Consensus/ConsensusMessage.cs b/neo/Consensus/ConsensusMessage.cs
deleted file mode 100644
index bf07dd2fbf..0000000000
--- a/neo/Consensus/ConsensusMessage.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Neo.IO;
-using Neo.IO.Caching;
-using System;
-using System.IO;
-
-namespace Neo.Consensus
-{
- internal abstract class ConsensusMessage : ISerializable
- {
- ///
- /// Reflection cache for ConsensusMessageType
- ///
- private static ReflectionCache ReflectionCache = ReflectionCache.CreateFromEnum();
-
- public readonly ConsensusMessageType Type;
- public byte ViewNumber;
-
- public int Size => sizeof(ConsensusMessageType) + sizeof(byte);
-
- protected ConsensusMessage(ConsensusMessageType type)
- {
- this.Type = type;
- }
-
- public virtual void Deserialize(BinaryReader reader)
- {
- if (Type != (ConsensusMessageType)reader.ReadByte())
- throw new FormatException();
- ViewNumber = reader.ReadByte();
- }
-
- public static ConsensusMessage DeserializeFrom(byte[] data)
- {
- ConsensusMessage message = ReflectionCache.CreateInstance(data[0]);
- if (message == null) throw new FormatException();
-
- using (MemoryStream ms = new MemoryStream(data, false))
- using (BinaryReader r = new BinaryReader(ms))
- {
- message.Deserialize(r);
- }
- return message;
- }
-
- public virtual void Serialize(BinaryWriter writer)
- {
- writer.Write((byte)Type);
- writer.Write(ViewNumber);
- }
- }
-}
diff --git a/neo/Consensus/ConsensusMessageType.cs b/neo/Consensus/ConsensusMessageType.cs
deleted file mode 100644
index b57dbc3214..0000000000
--- a/neo/Consensus/ConsensusMessageType.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using Neo.IO.Caching;
-
-namespace Neo.Consensus
-{
- internal enum ConsensusMessageType : byte
- {
- [ReflectionCache(typeof(ChangeView))]
- ChangeView = 0x00,
- [ReflectionCache(typeof(PrepareRequest))]
- PrepareRequest = 0x20,
- [ReflectionCache(typeof(PrepareResponse))]
- PrepareResponse = 0x21,
- }
-}
diff --git a/neo/Consensus/ConsensusService.cs b/neo/Consensus/ConsensusService.cs
deleted file mode 100644
index 532d0d1722..0000000000
--- a/neo/Consensus/ConsensusService.cs
+++ /dev/null
@@ -1,372 +0,0 @@
-using Neo.Core;
-using Neo.Cryptography;
-using Neo.IO;
-using Neo.Network;
-using Neo.Network.Payloads;
-using Neo.SmartContract;
-using Neo.Wallets;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-
-namespace Neo.Consensus
-{
- public class ConsensusService : IDisposable
- {
- private ConsensusContext context = new ConsensusContext();
- private LocalNode localNode;
- private Wallet wallet;
- private Timer timer;
- private uint timer_height;
- private byte timer_view;
- private DateTime block_received_time;
- private bool started = false;
-
- public ConsensusService(LocalNode localNode, Wallet wallet)
- {
- this.localNode = localNode;
- this.wallet = wallet;
- this.timer = new Timer(OnTimeout, null, Timeout.Infinite, Timeout.Infinite);
- }
-
- private bool AddTransaction(Transaction tx, bool verify)
- {
- if (Blockchain.Default.ContainsTransaction(tx.Hash) ||
- (verify && !tx.Verify(context.Transactions.Values)) ||
- !CheckPolicy(tx))
- {
- Log($"reject tx: {tx.Hash}{Environment.NewLine}{tx.ToArray().ToHexString()}");
- RequestChangeView();
- return false;
- }
- context.Transactions[tx.Hash] = tx;
- if (context.TransactionHashes.Length == context.Transactions.Count)
- {
- if (Blockchain.GetConsensusAddress(Blockchain.Default.GetValidators(context.Transactions.Values).ToArray()).Equals(context.NextConsensus))
- {
- Log($"send perpare response");
- context.State |= ConsensusState.SignatureSent;
- context.Signatures[context.MyIndex] = context.MakeHeader().Sign(context.KeyPair);
- SignAndRelay(context.MakePrepareResponse(context.Signatures[context.MyIndex]));
- CheckSignatures();
- }
- else
- {
- RequestChangeView();
- return false;
- }
- }
- return true;
- }
-
- private void Blockchain_PersistCompleted(object sender, Block block)
- {
- Log($"persist block: {block.Hash}");
- block_received_time = DateTime.Now;
- InitializeConsensus(0);
- }
-
- private void CheckExpectedView(byte view_number)
- {
- if (context.ViewNumber == view_number) return;
- if (context.ExpectedView.Count(p => p == view_number) >= context.M)
- {
- InitializeConsensus(view_number);
- }
- }
-
- protected virtual bool CheckPolicy(Transaction tx)
- {
- return true;
- }
-
- private void CheckSignatures()
- {
- if (context.Signatures.Count(p => p != null) >= context.M && context.TransactionHashes.All(p => context.Transactions.ContainsKey(p)))
- {
- Contract contract = Contract.CreateMultiSigContract(context.M, context.Validators);
- Block block = context.MakeHeader();
- ContractParametersContext sc = new ContractParametersContext(block);
- for (int i = 0, j = 0; i < context.Validators.Length && j < context.M; i++)
- if (context.Signatures[i] != null)
- {
- sc.AddSignature(contract, context.Validators[i], context.Signatures[i]);
- j++;
- }
- sc.Verifiable.Scripts = sc.GetScripts();
- block.Transactions = context.TransactionHashes.Select(p => context.Transactions[p]).ToArray();
- Log($"relay block: {block.Hash}");
- if (!localNode.Relay(block))
- Log($"reject block: {block.Hash}");
- context.State |= ConsensusState.BlockSent;
- }
- }
-
- private MinerTransaction CreateMinerTransaction(IEnumerable transactions, uint height, ulong nonce)
- {
- Fixed8 amount_netfee = Block.CalculateNetFee(transactions);
- TransactionOutput[] outputs = amount_netfee == Fixed8.Zero ? new TransactionOutput[0] : new[] { new TransactionOutput
- {
- AssetId = Blockchain.UtilityToken.Hash,
- Value = amount_netfee,
- ScriptHash = wallet.GetChangeAddress()
- } };
- return new MinerTransaction
- {
- Nonce = (uint)(nonce % (uint.MaxValue + 1ul)),
- Attributes = new TransactionAttribute[0],
- Inputs = new CoinReference[0],
- Outputs = outputs,
- Scripts = new Witness[0]
- };
- }
-
- public void Dispose()
- {
- Log("OnStop");
- if (timer != null) timer.Dispose();
- if (started)
- {
- Blockchain.PersistCompleted -= Blockchain_PersistCompleted;
- LocalNode.InventoryReceiving -= LocalNode_InventoryReceiving;
- LocalNode.InventoryReceived -= LocalNode_InventoryReceived;
- }
- }
-
- private static ulong GetNonce()
- {
- byte[] nonce = new byte[sizeof(ulong)];
- Random rand = new Random();
- rand.NextBytes(nonce);
- return nonce.ToUInt64(0);
- }
-
- private void InitializeConsensus(byte view_number)
- {
- lock (context)
- {
- if (view_number == 0)
- context.Reset(wallet);
- else
- context.ChangeView(view_number);
- if (context.MyIndex < 0) return;
- Log($"initialize: height={context.BlockIndex} view={view_number} index={context.MyIndex} role={(context.MyIndex == context.PrimaryIndex ? ConsensusState.Primary : ConsensusState.Backup)}");
- if (context.MyIndex == context.PrimaryIndex)
- {
- context.State |= ConsensusState.Primary;
- timer_height = context.BlockIndex;
- timer_view = view_number;
- TimeSpan span = DateTime.Now - block_received_time;
- if (span >= Blockchain.TimePerBlock)
- timer.Change(0, Timeout.Infinite);
- else
- timer.Change(Blockchain.TimePerBlock - span, Timeout.InfiniteTimeSpan);
- }
- else
- {
- context.State = ConsensusState.Backup;
- timer_height = context.BlockIndex;
- timer_view = view_number;
- timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (view_number + 1)), Timeout.InfiniteTimeSpan);
- }
- }
- }
-
- private void LocalNode_InventoryReceived(object sender, IInventory inventory)
- {
- ConsensusPayload payload = inventory as ConsensusPayload;
- if (payload != null)
- {
- lock (context)
- {
- if (payload.ValidatorIndex == context.MyIndex) return;
-
- if (payload.Version != ConsensusContext.Version)
- return;
- if (payload.PrevHash != context.PrevHash || payload.BlockIndex != context.BlockIndex)
- {
- // Request blocks
-
- if (Blockchain.Default?.Height + 1 < payload.BlockIndex)
- {
- Log($"chain sync: expected={payload.BlockIndex} current: {Blockchain.Default?.Height}");
-
- localNode.RequestGetBlocks();
- }
-
- return;
- }
-
- if (payload.ValidatorIndex >= context.Validators.Length) return;
- ConsensusMessage message;
- try
- {
- message = ConsensusMessage.DeserializeFrom(payload.Data);
- }
- catch
- {
- return;
- }
- if (message.ViewNumber != context.ViewNumber && message.Type != ConsensusMessageType.ChangeView)
- return;
- switch (message.Type)
- {
- case ConsensusMessageType.ChangeView:
- OnChangeViewReceived(payload, (ChangeView)message);
- break;
- case ConsensusMessageType.PrepareRequest:
- OnPrepareRequestReceived(payload, (PrepareRequest)message);
- break;
- case ConsensusMessageType.PrepareResponse:
- OnPrepareResponseReceived(payload, (PrepareResponse)message);
- break;
- }
- }
- }
- }
-
- private void LocalNode_InventoryReceiving(object sender, InventoryReceivingEventArgs e)
- {
- Transaction tx = e.Inventory as Transaction;
- if (tx != null)
- {
- lock (context)
- {
- if (!context.State.HasFlag(ConsensusState.Backup) || !context.State.HasFlag(ConsensusState.RequestReceived) || context.State.HasFlag(ConsensusState.SignatureSent) || context.State.HasFlag(ConsensusState.ViewChanging))
- return;
- if (context.Transactions.ContainsKey(tx.Hash)) return;
- if (!context.TransactionHashes.Contains(tx.Hash)) return;
- AddTransaction(tx, true);
- e.Cancel = true;
- }
- }
- }
-
- protected virtual void Log(string message)
- {
- }
-
- private void OnChangeViewReceived(ConsensusPayload payload, ChangeView message)
- {
- Log($"{nameof(OnChangeViewReceived)}: height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex} nv={message.NewViewNumber}");
- if (message.NewViewNumber <= context.ExpectedView[payload.ValidatorIndex])
- return;
- context.ExpectedView[payload.ValidatorIndex] = message.NewViewNumber;
- CheckExpectedView(message.NewViewNumber);
- }
-
- private void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest message)
- {
- Log($"{nameof(OnPrepareRequestReceived)}: height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex} tx={message.TransactionHashes.Length}");
- if (!context.State.HasFlag(ConsensusState.Backup) || context.State.HasFlag(ConsensusState.RequestReceived))
- return;
- if (payload.ValidatorIndex != context.PrimaryIndex) return;
- if (payload.Timestamp <= Blockchain.Default.GetHeader(context.PrevHash).Timestamp || payload.Timestamp > DateTime.Now.AddMinutes(10).ToTimestamp())
- {
- Log($"Timestamp incorrect: {payload.Timestamp}");
- return;
- }
- context.State |= ConsensusState.RequestReceived;
- context.Timestamp = payload.Timestamp;
- context.Nonce = message.Nonce;
- context.NextConsensus = message.NextConsensus;
- context.TransactionHashes = message.TransactionHashes;
- context.Transactions = new Dictionary();
- if (!Crypto.Default.VerifySignature(context.MakeHeader().GetHashData(), message.Signature, context.Validators[payload.ValidatorIndex].EncodePoint(false))) return;
- context.Signatures = new byte[context.Validators.Length][];
- context.Signatures[payload.ValidatorIndex] = message.Signature;
- Dictionary mempool = LocalNode.GetMemoryPool().ToDictionary(p => p.Hash);
- foreach (UInt256 hash in context.TransactionHashes.Skip(1))
- {
- if (mempool.TryGetValue(hash, out Transaction tx))
- if (!AddTransaction(tx, false))
- return;
- }
- if (!AddTransaction(message.MinerTransaction, true)) return;
- LocalNode.AllowHashes(context.TransactionHashes.Except(context.Transactions.Keys));
- if (context.Transactions.Count < context.TransactionHashes.Length)
- localNode.SynchronizeMemoryPool();
- }
-
- private void OnPrepareResponseReceived(ConsensusPayload payload, PrepareResponse message)
- {
- Log($"{nameof(OnPrepareResponseReceived)}: height={payload.BlockIndex} view={message.ViewNumber} index={payload.ValidatorIndex}");
- if (context.State.HasFlag(ConsensusState.BlockSent)) return;
- if (context.Signatures[payload.ValidatorIndex] != null) return;
- Block header = context.MakeHeader();
- if (header == null || !Crypto.Default.VerifySignature(header.GetHashData(), message.Signature, context.Validators[payload.ValidatorIndex].EncodePoint(false))) return;
- context.Signatures[payload.ValidatorIndex] = message.Signature;
- CheckSignatures();
- }
-
- private void OnTimeout(object state)
- {
- lock (context)
- {
- if (timer_height != context.BlockIndex || timer_view != context.ViewNumber) return;
- Log($"timeout: height={timer_height} view={timer_view} state={context.State}");
- if (context.State.HasFlag(ConsensusState.Primary) && !context.State.HasFlag(ConsensusState.RequestSent))
- {
- Log($"send perpare request: height={timer_height} view={timer_view}");
- context.State |= ConsensusState.RequestSent;
- if (!context.State.HasFlag(ConsensusState.SignatureSent))
- {
- context.Timestamp = Math.Max(DateTime.Now.ToTimestamp(), Blockchain.Default.GetHeader(context.PrevHash).Timestamp + 1);
- context.Nonce = GetNonce();
- List transactions = LocalNode.GetMemoryPool().Where(p => CheckPolicy(p)).ToList();
- if (transactions.Count >= Settings.Default.MaxTransactionsPerBlock)
- transactions = transactions.OrderByDescending(p => p.NetworkFee / p.Size).Take(Settings.Default.MaxTransactionsPerBlock - 1).ToList();
- transactions.Insert(0, CreateMinerTransaction(transactions, context.BlockIndex, context.Nonce));
- context.TransactionHashes = transactions.Select(p => p.Hash).ToArray();
- context.Transactions = transactions.ToDictionary(p => p.Hash);
- context.NextConsensus = Blockchain.GetConsensusAddress(Blockchain.Default.GetValidators(transactions).ToArray());
- context.Signatures[context.MyIndex] = context.MakeHeader().Sign(context.KeyPair);
- }
- SignAndRelay(context.MakePrepareRequest());
- timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (timer_view + 1)), Timeout.InfiniteTimeSpan);
- }
- else if ((context.State.HasFlag(ConsensusState.Primary) && context.State.HasFlag(ConsensusState.RequestSent)) || context.State.HasFlag(ConsensusState.Backup))
- {
- RequestChangeView();
- }
- }
- }
-
- private void RequestChangeView()
- {
- context.State |= ConsensusState.ViewChanging;
- context.ExpectedView[context.MyIndex]++;
- Log($"request change view: height={context.BlockIndex} view={context.ViewNumber} nv={context.ExpectedView[context.MyIndex]} state={context.State}");
- timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock << (context.ExpectedView[context.MyIndex] + 1)), Timeout.InfiniteTimeSpan);
- SignAndRelay(context.MakeChangeView());
- CheckExpectedView(context.ExpectedView[context.MyIndex]);
- }
-
- private void SignAndRelay(ConsensusPayload payload)
- {
- ContractParametersContext sc;
- try
- {
- sc = new ContractParametersContext(payload);
- wallet.Sign(sc);
- }
- catch (InvalidOperationException)
- {
- return;
- }
- sc.Verifiable.Scripts = sc.GetScripts();
- localNode.RelayDirectly(payload);
- }
-
- public void Start()
- {
- Log("OnStart");
- started = true;
- Blockchain.PersistCompleted += Blockchain_PersistCompleted;
- LocalNode.InventoryReceiving += LocalNode_InventoryReceiving;
- LocalNode.InventoryReceived += LocalNode_InventoryReceived;
- InitializeConsensus(0);
- }
- }
-}
diff --git a/neo/Consensus/ConsensusState.cs b/neo/Consensus/ConsensusState.cs
deleted file mode 100644
index 15b570d08b..0000000000
--- a/neo/Consensus/ConsensusState.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-
-namespace Neo.Consensus
-{
- [Flags]
- internal enum ConsensusState : byte
- {
- Initial = 0x00,
- Primary = 0x01,
- Backup = 0x02,
- RequestSent = 0x04,
- RequestReceived = 0x08,
- SignatureSent = 0x10,
- BlockSent = 0x20,
- ViewChanging = 0x40,
- }
-}
diff --git a/neo/Consensus/PrepareRequest.cs b/neo/Consensus/PrepareRequest.cs
deleted file mode 100644
index a9e9032a54..0000000000
--- a/neo/Consensus/PrepareRequest.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using Neo.Core;
-using Neo.IO;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Consensus
-{
- internal class PrepareRequest : ConsensusMessage
- {
- public ulong Nonce;
- public UInt160 NextConsensus;
- public UInt256[] TransactionHashes;
- public MinerTransaction MinerTransaction;
- public byte[] Signature;
-
- public PrepareRequest()
- : base(ConsensusMessageType.PrepareRequest)
- {
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- Nonce = reader.ReadUInt64();
- NextConsensus = reader.ReadSerializable();
- TransactionHashes = reader.ReadSerializableArray();
- if (TransactionHashes.Distinct().Count() != TransactionHashes.Length)
- throw new FormatException();
- MinerTransaction = reader.ReadSerializable();
- if (MinerTransaction.Hash != TransactionHashes[0])
- throw new FormatException();
- Signature = reader.ReadBytes(64);
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(Nonce);
- writer.Write(NextConsensus);
- writer.Write(TransactionHashes);
- writer.Write(MinerTransaction);
- writer.Write(Signature);
- }
- }
-}
diff --git a/neo/Consensus/PrepareResponse.cs b/neo/Consensus/PrepareResponse.cs
deleted file mode 100644
index d7c95c917a..0000000000
--- a/neo/Consensus/PrepareResponse.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.IO;
-
-namespace Neo.Consensus
-{
- internal class PrepareResponse : ConsensusMessage
- {
- public byte[] Signature;
-
- public PrepareResponse()
- : base(ConsensusMessageType.PrepareResponse)
- {
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- Signature = reader.ReadBytes(64);
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(Signature);
- }
- }
-}
diff --git a/neo/Core/AccountState.cs b/neo/Core/AccountState.cs
deleted file mode 100644
index 75e50b54ad..0000000000
--- a/neo/Core/AccountState.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.VM;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- public class AccountState : StateBase, ICloneable
- {
- public UInt160 ScriptHash;
- public bool IsFrozen;
- public ECPoint[] Votes;
- public Dictionary Balances;
-
- public override int Size => base.Size + ScriptHash.Size + sizeof(bool) + Votes.GetVarSize()
- + IO.Helper.GetVarSize(Balances.Count) + Balances.Count * (32 + 8);
-
- public AccountState() { }
-
- public AccountState(UInt160 hash)
- {
- this.ScriptHash = hash;
- this.IsFrozen = false;
- this.Votes = new ECPoint[0];
- this.Balances = new Dictionary();
- }
-
- AccountState ICloneable.Clone()
- {
- return new AccountState
- {
- ScriptHash = ScriptHash,
- IsFrozen = IsFrozen,
- Votes = Votes,
- Balances = Balances.ToDictionary(p => p.Key, p => p.Value)
- };
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- ScriptHash = reader.ReadSerializable();
- IsFrozen = reader.ReadBoolean();
- Votes = new ECPoint[reader.ReadVarInt()];
- for (int i = 0; i < Votes.Length; i++)
- Votes[i] = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1);
- int count = (int)reader.ReadVarInt();
- Balances = new Dictionary(count);
- for (int i = 0; i < count; i++)
- {
- UInt256 assetId = reader.ReadSerializable();
- Fixed8 value = reader.ReadSerializable();
- Balances.Add(assetId, value);
- }
- }
-
- void ICloneable.FromReplica(AccountState replica)
- {
- ScriptHash = replica.ScriptHash;
- IsFrozen = replica.IsFrozen;
- Votes = replica.Votes;
- Balances = replica.Balances;
- }
-
- public Fixed8 GetBalance(UInt256 asset_id)
- {
- if (!Balances.TryGetValue(asset_id, out Fixed8 value))
- value = Fixed8.Zero;
- return value;
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(ScriptHash);
- writer.Write(IsFrozen);
- writer.Write(Votes);
- var balances = Balances.Where(p => p.Value > Fixed8.Zero).ToArray();
- writer.WriteVarInt(balances.Length);
- foreach (var pair in balances)
- {
- writer.Write(pair.Key);
- writer.Write(pair.Value);
- }
- }
-
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["script_hash"] = ScriptHash.ToString();
- json["frozen"] = IsFrozen;
- json["votes"] = new JArray(Votes.Select(p => (JObject)p.ToString()));
- json["balances"] = new JArray(Balances.Select(p =>
- {
- JObject balance = new JObject();
- balance["asset"] = p.Key.ToString();
- balance["value"] = p.Value.ToString();
- return balance;
- }));
- return json;
- }
- }
-}
diff --git a/neo/Core/ApplicationExecutedEventArgs.cs b/neo/Core/ApplicationExecutedEventArgs.cs
deleted file mode 100644
index aca7ddb75b..0000000000
--- a/neo/Core/ApplicationExecutedEventArgs.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using Neo.SmartContract;
-using Neo.VM;
-using System;
-using System.Linq;
-
-namespace Neo.Core
-{
- public class ApplicationExecutedEventArgs : EventArgs
- {
- public InvocationTransaction Transaction { get; }
- public VMState VMState { get; }
- public Fixed8 GasConsumed { get; }
- public StackItem[] Stack { get; }
- public NotifyEventArgs[] Notifications { get; }
-
- public ApplicationExecutedEventArgs(InvocationTransaction tx, NotifyEventArgs[] notifications, ApplicationEngine engine)
- {
- this.Transaction = tx;
- this.VMState = engine.State;
- this.GasConsumed = engine.GasConsumed;
- this.Stack = engine.EvaluationStack.ToArray();
- this.Notifications = notifications;
- }
- }
-}
diff --git a/neo/Core/AssetState.cs b/neo/Core/AssetState.cs
deleted file mode 100644
index f18529fdbc..0000000000
--- a/neo/Core/AssetState.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.VM;
-using Neo.Wallets;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- public class AssetState : StateBase, ICloneable
- {
- public UInt256 AssetId;
- public AssetType AssetType;
- public string Name;
- public Fixed8 Amount;
- public Fixed8 Available;
- public byte Precision;
- public const byte FeeMode = 0;
- public Fixed8 Fee;
- public UInt160 FeeAddress;
- public ECPoint Owner;
- public UInt160 Admin;
- public UInt160 Issuer;
- public uint Expiration;
- public bool IsFrozen;
-
- public override int Size => base.Size + AssetId.Size + sizeof(AssetType) + Name.GetVarSize() + Amount.Size + Available.Size + sizeof(byte) + sizeof(byte) + Fee.Size + FeeAddress.Size + Owner.Size + Admin.Size + Issuer.Size + sizeof(uint) + sizeof(bool);
-
- AssetState ICloneable.Clone()
- {
- return new AssetState
- {
- AssetId = AssetId,
- AssetType = AssetType,
- Name = Name,
- Amount = Amount,
- Available = Available,
- Precision = Precision,
- //FeeMode = FeeMode,
- Fee = Fee,
- FeeAddress = FeeAddress,
- Owner = Owner,
- Admin = Admin,
- Issuer = Issuer,
- Expiration = Expiration,
- IsFrozen = IsFrozen,
- _names = _names
- };
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- AssetId = reader.ReadSerializable();
- AssetType = (AssetType)reader.ReadByte();
- Name = reader.ReadVarString();
- Amount = reader.ReadSerializable();
- Available = reader.ReadSerializable();
- Precision = reader.ReadByte();
- reader.ReadByte(); //FeeMode
- Fee = reader.ReadSerializable(); //Fee
- FeeAddress = reader.ReadSerializable();
- Owner = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1);
- Admin = reader.ReadSerializable();
- Issuer = reader.ReadSerializable();
- Expiration = reader.ReadUInt32();
- IsFrozen = reader.ReadBoolean();
- }
-
- void ICloneable.FromReplica(AssetState replica)
- {
- AssetId = replica.AssetId;
- AssetType = replica.AssetType;
- Name = replica.Name;
- Amount = replica.Amount;
- Available = replica.Available;
- Precision = replica.Precision;
- //FeeMode = replica.FeeMode;
- Fee = replica.Fee;
- FeeAddress = replica.FeeAddress;
- Owner = replica.Owner;
- Admin = replica.Admin;
- Issuer = replica.Issuer;
- Expiration = replica.Expiration;
- IsFrozen = replica.IsFrozen;
- _names = replica._names;
- }
-
- private Dictionary _names;
- public string GetName(CultureInfo culture = null)
- {
- if (AssetType == AssetType.GoverningToken) return "NEO";
- if (AssetType == AssetType.UtilityToken) return "NeoGas";
- if (_names == null)
- {
- JObject name_obj;
- try
- {
- name_obj = JObject.Parse(Name);
- }
- catch (FormatException)
- {
- name_obj = Name;
- }
- if (name_obj is JString)
- _names = new Dictionary { { new CultureInfo("en"), name_obj.AsString() } };
- else
- _names = ((JArray)name_obj).Where(p => p.ContainsProperty("lang") && p.ContainsProperty("name")).ToDictionary(p => new CultureInfo(p["lang"].AsString()), p => p["name"].AsString());
- }
- if (culture == null) culture = CultureInfo.CurrentCulture;
- if (_names.TryGetValue(culture, out string name))
- {
- return name;
- }
- else if (_names.TryGetValue(en, out name))
- {
- return name;
- }
- else
- {
- return _names.Values.First();
- }
- }
-
- private static readonly CultureInfo en = new CultureInfo("en");
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(AssetId);
- writer.Write((byte)AssetType);
- writer.WriteVarString(Name);
- writer.Write(Amount);
- writer.Write(Available);
- writer.Write(Precision);
- writer.Write(FeeMode);
- writer.Write(Fee);
- writer.Write(FeeAddress);
- writer.Write(Owner);
- writer.Write(Admin);
- writer.Write(Issuer);
- writer.Write(Expiration);
- writer.Write(IsFrozen);
- }
-
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["id"] = AssetId.ToString();
- json["type"] = AssetType;
- try
- {
- json["name"] = Name == "" ? null : JObject.Parse(Name);
- }
- catch (FormatException)
- {
- json["name"] = Name;
- }
- json["amount"] = Amount.ToString();
- json["available"] = Available.ToString();
- json["precision"] = Precision;
- json["owner"] = Owner.ToString();
- json["admin"] = Wallet.ToAddress(Admin);
- json["issuer"] = Wallet.ToAddress(Issuer);
- json["expiration"] = Expiration;
- json["frozen"] = IsFrozen;
- return json;
- }
-
- public override string ToString()
- {
- return GetName();
- }
- }
-}
diff --git a/neo/Core/AssetType.cs b/neo/Core/AssetType.cs
deleted file mode 100644
index b70f517d26..0000000000
--- a/neo/Core/AssetType.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Neo.Core
-{
- ///
- /// 资产类别
- ///
- public enum AssetType : byte
- {
- CreditFlag = 0x40,
- DutyFlag = 0x80,
-
- GoverningToken = 0x00,
- UtilityToken = 0x01,
- Currency = 0x08,
- Share = DutyFlag | 0x10,
- Invoice = DutyFlag | 0x18,
- Token = CreditFlag | 0x20,
- }
-}
diff --git a/neo/Core/Block.cs b/neo/Core/Block.cs
deleted file mode 100644
index ead1e9e462..0000000000
--- a/neo/Core/Block.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-using Neo.Cryptography;
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.Network;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- ///
- /// 区块或区块头
- ///
- public class Block : BlockBase, IInventory, IEquatable
- {
- ///
- /// 交易列表
- ///
- public Transaction[] Transactions;
-
- private Header _header = null;
- ///
- /// 该区块的区块头
- ///
- public Header Header
- {
- get
- {
- if (_header == null)
- {
- _header = new Header
- {
- PrevHash = PrevHash,
- MerkleRoot = MerkleRoot,
- Timestamp = Timestamp,
- Index = Index,
- ConsensusData = ConsensusData,
- NextConsensus = NextConsensus,
- Script = Script
- };
- }
- return _header;
- }
- }
-
- ///
- /// 资产清单的类型
- ///
- InventoryType IInventory.InventoryType => InventoryType.Block;
-
- public override int Size => base.Size + Transactions.GetVarSize();
-
- public static Fixed8 CalculateNetFee(IEnumerable transactions)
- {
- Transaction[] ts = transactions.Where(p => p.Type != TransactionType.MinerTransaction && p.Type != TransactionType.ClaimTransaction).ToArray();
- Fixed8 amount_in = ts.SelectMany(p => p.References.Values.Where(o => o.AssetId == Blockchain.UtilityToken.Hash)).Sum(p => p.Value);
- Fixed8 amount_out = ts.SelectMany(p => p.Outputs.Where(o => o.AssetId == Blockchain.UtilityToken.Hash)).Sum(p => p.Value);
- Fixed8 amount_sysfee = ts.Sum(p => p.SystemFee);
- return amount_in - amount_out - amount_sysfee;
- }
-
- ///
- /// 反序列化
- ///
- /// 数据来源
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- Transactions = new Transaction[reader.ReadVarInt(0x10000)];
- if (Transactions.Length == 0) throw new FormatException();
- for (int i = 0; i < Transactions.Length; i++)
- {
- Transactions[i] = Transaction.DeserializeFrom(reader);
- }
- if (MerkleTree.ComputeRoot(Transactions.Select(p => p.Hash).ToArray()) != MerkleRoot)
- throw new FormatException();
- }
-
- ///
- /// 比较当前区块与指定区块是否相等
- ///
- /// 要比较的区块
- /// 返回对象是否相等
- public bool Equals(Block other)
- {
- if (ReferenceEquals(this, other)) return true;
- if (ReferenceEquals(null, other)) return false;
- return Hash.Equals(other.Hash);
- }
-
- ///
- /// 比较当前区块与指定区块是否相等
- ///
- /// 要比较的区块
- /// 返回对象是否相等
- public override bool Equals(object obj)
- {
- return Equals(obj as Block);
- }
-
- public static Block FromTrimmedData(byte[] data, int index, Func txSelector)
- {
- Block block = new Block();
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- using (BinaryReader reader = new BinaryReader(ms))
- {
- ((IVerifiable)block).DeserializeUnsigned(reader);
- reader.ReadByte(); block.Script = reader.ReadSerializable();
- block.Transactions = new Transaction[reader.ReadVarInt(0x10000000)];
- for (int i = 0; i < block.Transactions.Length; i++)
- {
- block.Transactions[i] = txSelector(reader.ReadSerializable());
- }
- }
- return block;
- }
-
- ///
- /// 获得区块的HashCode
- ///
- /// 返回区块的HashCode
- public override int GetHashCode()
- {
- return Hash.GetHashCode();
- }
-
- ///
- /// 根据区块中所有交易的Hash生成MerkleRoot
- ///
- public void RebuildMerkleRoot()
- {
- MerkleRoot = MerkleTree.ComputeRoot(Transactions.Select(p => p.Hash).ToArray());
- }
-
- ///
- /// 序列化
- ///
- /// 存放序列化后的数据
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(Transactions);
- }
-
- ///
- /// 变成json对象
- ///
- /// 返回json对象
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["tx"] = Transactions.Select(p => p.ToJson()).ToArray();
- return json;
- }
-
- ///
- /// 把区块对象变为只包含区块头和交易Hash的字节数组,去除交易数据
- ///
- /// 返回只包含区块头和交易Hash的字节数组
- public byte[] Trim()
- {
- using (MemoryStream ms = new MemoryStream())
- using (BinaryWriter writer = new BinaryWriter(ms))
- {
- ((IVerifiable)this).SerializeUnsigned(writer);
- writer.Write((byte)1); writer.Write(Script);
- writer.Write(Transactions.Select(p => p.Hash).ToArray());
- writer.Flush();
- return ms.ToArray();
- }
- }
-
- ///
- /// 验证该区块是否合法
- ///
- /// 是否同时验证区块中的每一笔交易
- /// 返回该区块的合法性,返回true即为合法,否则,非法。
- public bool Verify(bool completely)
- {
- if (!Verify()) return false;
- if (Transactions[0].Type != TransactionType.MinerTransaction || Transactions.Skip(1).Any(p => p.Type == TransactionType.MinerTransaction))
- return false;
- if (completely)
- {
- if (NextConsensus != Blockchain.GetConsensusAddress(Blockchain.Default.GetValidators(Transactions).ToArray()))
- return false;
- foreach (Transaction tx in Transactions)
- if (!tx.Verify(Transactions.Where(p => !p.Hash.Equals(tx.Hash)))) return false;
- Transaction tx_gen = Transactions.FirstOrDefault(p => p.Type == TransactionType.MinerTransaction);
- if (tx_gen?.Outputs.Sum(p => p.Value) != CalculateNetFee(Transactions)) return false;
- }
- return true;
- }
- }
-}
diff --git a/neo/Core/BlockBase.cs b/neo/Core/BlockBase.cs
deleted file mode 100644
index 9b64c43a10..0000000000
--- a/neo/Core/BlockBase.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-using Neo.Cryptography;
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.VM;
-using Neo.Wallets;
-using System;
-using System.IO;
-
-namespace Neo.Core
-{
- public abstract class BlockBase : IVerifiable
- {
- ///
- /// 区块版本
- ///
- public uint Version;
- ///
- /// 前一个区块的散列值
- ///
- public UInt256 PrevHash;
- ///
- /// 该区块中所有交易的Merkle树的根
- ///
- public UInt256 MerkleRoot;
- ///
- /// 时间戳
- ///
- public uint Timestamp;
- ///
- /// 区块高度
- ///
- public uint Index;
- public ulong ConsensusData;
- ///
- /// 下一个区块的记账合约的散列值
- ///
- public UInt160 NextConsensus;
- ///
- /// 用于验证该区块的脚本
- ///
- public Witness Script;
-
- private UInt256 _hash = null;
- public UInt256 Hash
- {
- get
- {
- if (_hash == null)
- {
- _hash = new UInt256(Crypto.Default.Hash256(this.GetHashData()));
- }
- return _hash;
- }
- }
-
- Witness[] IVerifiable.Scripts
- {
- get
- {
- return new[] { Script };
- }
- set
- {
- if (value.Length != 1) throw new ArgumentException();
- Script = value[0];
- }
- }
-
- public virtual int Size => sizeof(uint) + PrevHash.Size + MerkleRoot.Size + sizeof(uint) + sizeof(uint) + sizeof(ulong) + NextConsensus.Size + 1 + Script.Size;
-
- public virtual void Deserialize(BinaryReader reader)
- {
- ((IVerifiable)this).DeserializeUnsigned(reader);
- if (reader.ReadByte() != 1) throw new FormatException();
- Script = reader.ReadSerializable();
- }
-
- void IVerifiable.DeserializeUnsigned(BinaryReader reader)
- {
- Version = reader.ReadUInt32();
- PrevHash = reader.ReadSerializable();
- MerkleRoot = reader.ReadSerializable();
- Timestamp = reader.ReadUInt32();
- Index = reader.ReadUInt32();
- ConsensusData = reader.ReadUInt64();
- NextConsensus = reader.ReadSerializable();
- }
-
- byte[] IScriptContainer.GetMessage()
- {
- return this.GetHashData();
- }
-
- UInt160[] IVerifiable.GetScriptHashesForVerifying()
- {
- if (PrevHash == UInt256.Zero)
- return new[] { Script.ScriptHash };
- Header prev_header = Blockchain.Default.GetHeader(PrevHash);
- if (prev_header == null) throw new InvalidOperationException();
- return new UInt160[] { prev_header.NextConsensus };
- }
-
- public virtual void Serialize(BinaryWriter writer)
- {
- ((IVerifiable)this).SerializeUnsigned(writer);
- writer.Write((byte)1); writer.Write(Script);
- }
-
- void IVerifiable.SerializeUnsigned(BinaryWriter writer)
- {
- writer.Write(Version);
- writer.Write(PrevHash);
- writer.Write(MerkleRoot);
- writer.Write(Timestamp);
- writer.Write(Index);
- writer.Write(ConsensusData);
- writer.Write(NextConsensus);
- }
-
- public virtual JObject ToJson()
- {
- JObject json = new JObject();
- json["hash"] = Hash.ToString();
- json["size"] = Size;
- json["version"] = Version;
- json["previousblockhash"] = PrevHash.ToString();
- json["merkleroot"] = MerkleRoot.ToString();
- json["time"] = Timestamp;
- json["index"] = Index;
- json["nonce"] = ConsensusData.ToString("x16");
- json["nextconsensus"] = Wallet.ToAddress(NextConsensus);
- json["script"] = Script.ToJson();
- return json;
- }
-
- public bool Verify()
- {
- if (Hash == Blockchain.GenesisBlock.Hash) return true;
- if (Blockchain.Default.ContainsBlock(Hash)) return true;
- Header prev_header = Blockchain.Default.GetHeader(PrevHash);
- if (prev_header == null) return false;
- if (prev_header.Index + 1 != Index) return false;
- if (prev_header.Timestamp >= Timestamp) return false;
- if (!this.VerifyScripts()) return false;
- return true;
- }
- }
-}
diff --git a/neo/Core/Blockchain.cs b/neo/Core/Blockchain.cs
deleted file mode 100644
index 0d752220db..0000000000
--- a/neo/Core/Blockchain.cs
+++ /dev/null
@@ -1,585 +0,0 @@
-using Neo.Cryptography;
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using Neo.IO.Caching;
-using Neo.SmartContract;
-using Neo.VM;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Neo.Core
-{
- ///
- /// 实现区块链功能的基类
- ///
- public abstract class Blockchain : IDisposable, IScriptTable
- {
- public static event EventHandler PersistCompleted;
-
- ///
- /// 产生每个区块的时间间隔,已秒为单位
- ///
- public const uint SecondsPerBlock = 15;
- public const uint DecrementInterval = 2000000;
- public const uint MaxValidators = 1024;
- public static readonly uint[] GenerationAmount = { 8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
- ///
- /// 产生每个区块的时间间隔
- ///
- public static readonly TimeSpan TimePerBlock = TimeSpan.FromSeconds(SecondsPerBlock);
- ///
- /// 后备记账人列表
- ///
- public static readonly ECPoint[] StandbyValidators = Settings.Default.StandbyValidators.OfType().Select(p => ECPoint.DecodePoint(p.HexToBytes(), ECCurve.Secp256r1)).ToArray();
-
- ///
- /// Return true if haven't got valid handle
- ///
- public abstract bool IsDisposed { get; }
-
-#pragma warning disable CS0612
- public static readonly RegisterTransaction GoverningToken = new RegisterTransaction
- {
- AssetType = AssetType.GoverningToken,
- Name = "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]",
- Amount = Fixed8.FromDecimal(100000000),
- Precision = 0,
- Owner = ECCurve.Secp256r1.Infinity,
- Admin = (new[] { (byte)OpCode.PUSHT }).ToScriptHash(),
- Attributes = new TransactionAttribute[0],
- Inputs = new CoinReference[0],
- Outputs = new TransactionOutput[0],
- Scripts = new Witness[0]
- };
-
- public static readonly RegisterTransaction UtilityToken = new RegisterTransaction
- {
- AssetType = AssetType.UtilityToken,
- Name = "[{\"lang\":\"zh-CN\",\"name\":\"小蚁币\"},{\"lang\":\"en\",\"name\":\"AntCoin\"}]",
- Amount = Fixed8.FromDecimal(GenerationAmount.Sum(p => p) * DecrementInterval),
- Precision = 8,
- Owner = ECCurve.Secp256r1.Infinity,
- Admin = (new[] { (byte)OpCode.PUSHF }).ToScriptHash(),
- Attributes = new TransactionAttribute[0],
- Inputs = new CoinReference[0],
- Outputs = new TransactionOutput[0],
- Scripts = new Witness[0]
- };
-#pragma warning restore CS0612
-
- ///
- /// 创世区块
- ///
- public static readonly Block GenesisBlock = new Block
- {
- PrevHash = UInt256.Zero,
- Timestamp = (new DateTime(2016, 7, 15, 15, 8, 21, DateTimeKind.Utc)).ToTimestamp(),
- Index = 0,
- ConsensusData = 2083236893, //向比特币致敬
- NextConsensus = GetConsensusAddress(StandbyValidators),
- Script = new Witness
- {
- InvocationScript = new byte[0],
- VerificationScript = new[] { (byte)OpCode.PUSHT }
- },
- Transactions = new Transaction[]
- {
- new MinerTransaction
- {
- Nonce = 2083236893,
- Attributes = new TransactionAttribute[0],
- Inputs = new CoinReference[0],
- Outputs = new TransactionOutput[0],
- Scripts = new Witness[0]
- },
- GoverningToken,
- UtilityToken,
- new IssueTransaction
- {
- Attributes = new TransactionAttribute[0],
- Inputs = new CoinReference[0],
- Outputs = new[]
- {
- new TransactionOutput
- {
- AssetId = GoverningToken.Hash,
- Value = GoverningToken.Amount,
- ScriptHash = Contract.CreateMultiSigRedeemScript(StandbyValidators.Length / 2 + 1, StandbyValidators).ToScriptHash()
- }
- },
- Scripts = new[]
- {
- new Witness
- {
- InvocationScript = new byte[0],
- VerificationScript = new[] { (byte)OpCode.PUSHT }
- }
- }
- }
- }
- };
-
- ///
- /// 当前最新区块散列值
- ///
- public abstract UInt256 CurrentBlockHash { get; }
- ///
- /// 当前最新区块头的散列值
- ///
- public abstract UInt256 CurrentHeaderHash { get; }
- ///
- /// 默认的区块链实例
- ///
- public static Blockchain Default { get; private set; } = null;
- ///
- /// 区块头高度
- ///
- public abstract uint HeaderHeight { get; }
- ///
- /// 区块高度
- ///
- public abstract uint Height { get; }
-
- static Blockchain()
- {
- GenesisBlock.RebuildMerkleRoot();
- }
-
- ///
- /// 将指定的区块添加到区块链中
- ///
- /// 要添加的区块
- /// 返回是否添加成功
- public abstract bool AddBlock(Block block);
-
- ///
- /// 将指定的区块头添加到区块头链中
- ///
- /// 要添加的区块头列表
- protected internal abstract void AddHeaders(IEnumerable headers);
-
- public static Fixed8 CalculateBonus(IEnumerable inputs, bool ignoreClaimed = true)
- {
- List unclaimed = new List();
- foreach (var group in inputs.GroupBy(p => p.PrevHash))
- {
- Dictionary claimable = Default.GetUnclaimed(group.Key);
- if (claimable == null || claimable.Count == 0)
- if (ignoreClaimed)
- continue;
- else
- throw new ArgumentException();
- foreach (CoinReference claim in group)
- {
- if (!claimable.TryGetValue(claim.PrevIndex, out SpentCoin claimed))
- if (ignoreClaimed)
- continue;
- else
- throw new ArgumentException();
- unclaimed.Add(claimed);
- }
- }
- return CalculateBonusInternal(unclaimed);
- }
-
- public static Fixed8 CalculateBonus(IEnumerable inputs, uint height_end)
- {
- List unclaimed = new List();
- foreach (var group in inputs.GroupBy(p => p.PrevHash))
- {
- Transaction tx = Default.GetTransaction(group.Key, out int height_start);
- if (tx == null) throw new ArgumentException();
- if (height_start == height_end) continue;
- foreach (CoinReference claim in group)
- {
- if (claim.PrevIndex >= tx.Outputs.Length || !tx.Outputs[claim.PrevIndex].AssetId.Equals(GoverningToken.Hash))
- throw new ArgumentException();
- unclaimed.Add(new SpentCoin
- {
- Output = tx.Outputs[claim.PrevIndex],
- StartHeight = (uint)height_start,
- EndHeight = height_end
- });
- }
- }
- return CalculateBonusInternal(unclaimed);
- }
-
- private static Fixed8 CalculateBonusInternal(IEnumerable unclaimed)
- {
- Fixed8 amount_claimed = Fixed8.Zero;
- foreach (var group in unclaimed.GroupBy(p => new { p.StartHeight, p.EndHeight }))
- {
- uint amount = 0;
- uint ustart = group.Key.StartHeight / DecrementInterval;
- if (ustart < GenerationAmount.Length)
- {
- uint istart = group.Key.StartHeight % DecrementInterval;
- uint uend = group.Key.EndHeight / DecrementInterval;
- uint iend = group.Key.EndHeight % DecrementInterval;
- if (uend >= GenerationAmount.Length)
- {
- uend = (uint)GenerationAmount.Length;
- iend = 0;
- }
- if (iend == 0)
- {
- uend--;
- iend = DecrementInterval;
- }
- while (ustart < uend)
- {
- amount += (DecrementInterval - istart) * GenerationAmount[ustart];
- ustart++;
- istart = 0;
- }
- amount += (iend - istart) * GenerationAmount[ustart];
- }
- amount += (uint)(Default.GetSysFeeAmount(group.Key.EndHeight - 1) - (group.Key.StartHeight == 0 ? 0 : Default.GetSysFeeAmount(group.Key.StartHeight - 1)));
- amount_claimed += group.Sum(p => p.Value) / 100000000 * amount;
- }
- return amount_claimed;
- }
-
- ///
- /// 判断区块链中是否包含指定的区块
- ///
- /// 区块编号
- /// 如果包含指定区块则返回true
- public abstract bool ContainsBlock(UInt256 hash);
-
- ///
- /// 判断区块链中是否包含指定的交易
- ///
- /// 交易编号
- /// 如果包含指定交易则返回true
- public abstract bool ContainsTransaction(UInt256 hash);
-
- public bool ContainsUnspent(CoinReference input)
- {
- return ContainsUnspent(input.PrevHash, input.PrevIndex);
- }
-
- public abstract bool ContainsUnspent(UInt256 hash, ushort index);
-
- public abstract MetaDataCache GetMetaData() where T : class, ISerializable, new();
-
- public abstract DataCache GetStates()
- where TKey : IEquatable, ISerializable, new()
- where TValue : StateBase, ICloneable, new();
-
- public abstract void Dispose();
-
- public abstract AccountState GetAccountState(UInt160 script_hash);
-
- public abstract AssetState GetAssetState(UInt256 asset_id);
-
- ///
- /// 根据指定的高度,返回对应的区块信息
- ///
- /// 区块高度
- /// 返回对应的区块信息
- public Block GetBlock(uint height)
- {
- UInt256 hash = GetBlockHash(height);
- if (hash == null) return null;
- return GetBlock(hash);
- }
-
- ///
- /// 根据指定的散列值,返回对应的区块信息
- ///
- /// 散列值
- /// 返回对应的区块信息
- public abstract Block GetBlock(UInt256 hash);
-
- ///
- /// 根据指定的高度,返回对应区块的散列值
- ///
- /// 区块高度
- /// 返回对应区块的散列值
- public abstract UInt256 GetBlockHash(uint height);
-
- public abstract ContractState GetContract(UInt160 hash);
-
- public abstract IEnumerable GetEnrollments();
-
- ///
- /// 根据指定的高度,返回对应的区块头信息
- ///
- /// 区块高度
- /// 返回对应的区块头信息
- public abstract Header GetHeader(uint height);
-
- ///
- /// 根据指定的散列值,返回对应的区块头信息
- ///
- /// 散列值
- /// 返回对应的区块头信息
- public abstract Header GetHeader(UInt256 hash);
-
- ///
- /// 获取记账人的合约地址
- ///
- /// 记账人的公钥列表
- /// 返回记账人的合约地址
- public static UInt160 GetConsensusAddress(ECPoint[] validators)
- {
- return Contract.CreateMultiSigRedeemScript(validators.Length - (validators.Length - 1) / 3, validators).ToScriptHash();
- }
-
- private List _validators = new List();
- ///
- /// 获取下一个区块的记账人列表
- ///
- /// 返回一组公钥,表示下一个区块的记账人列表
- public ECPoint[] GetValidators()
- {
- lock (_validators)
- {
- if (_validators.Count == 0)
- {
- _validators.AddRange(GetValidators(Enumerable.Empty()));
- }
- return _validators.ToArray();
- }
- }
-
- public virtual IEnumerable GetValidators(IEnumerable others)
- {
- DataCache accounts = GetStates();
- DataCache validators = GetStates();
- MetaDataCache validators_count = GetMetaData();
- foreach (Transaction tx in others)
- {
- foreach (TransactionOutput output in tx.Outputs)
- {
- AccountState account = accounts.GetAndChange(output.ScriptHash, () => new AccountState(output.ScriptHash));
- if (account.Balances.ContainsKey(output.AssetId))
- account.Balances[output.AssetId] += output.Value;
- else
- account.Balances[output.AssetId] = output.Value;
- if (output.AssetId.Equals(GoverningToken.Hash) && account.Votes.Length > 0)
- {
- foreach (ECPoint pubkey in account.Votes)
- validators.GetAndChange(pubkey, () => new ValidatorState(pubkey)).Votes += output.Value;
- validators_count.GetAndChange().Votes[account.Votes.Length - 1] += output.Value;
- }
- }
- foreach (var group in tx.Inputs.GroupBy(p => p.PrevHash))
- {
- Transaction tx_prev = GetTransaction(group.Key, out int height);
- foreach (CoinReference input in group)
- {
- TransactionOutput out_prev = tx_prev.Outputs[input.PrevIndex];
- AccountState account = accounts.GetAndChange(out_prev.ScriptHash);
- if (out_prev.AssetId.Equals(GoverningToken.Hash))
- {
- if (account.Votes.Length > 0)
- {
- foreach (ECPoint pubkey in account.Votes)
- {
- ValidatorState validator = validators.GetAndChange(pubkey);
- validator.Votes -= out_prev.Value;
- if (!validator.Registered && validator.Votes.Equals(Fixed8.Zero))
- validators.Delete(pubkey);
- }
- validators_count.GetAndChange().Votes[account.Votes.Length - 1] -= out_prev.Value;
- }
- }
- account.Balances[out_prev.AssetId] -= out_prev.Value;
- }
- }
- switch (tx)
- {
-#pragma warning disable CS0612
- case EnrollmentTransaction tx_enrollment:
- validators.GetAndChange(tx_enrollment.PublicKey, () => new ValidatorState(tx_enrollment.PublicKey)).Registered = true;
- break;
-#pragma warning restore CS0612
- case StateTransaction tx_state:
- foreach (StateDescriptor descriptor in tx_state.Descriptors)
- switch (descriptor.Type)
- {
- case StateType.Account:
- ProcessAccountStateDescriptor(descriptor, accounts, validators, validators_count);
- break;
- case StateType.Validator:
- ProcessValidatorStateDescriptor(descriptor, validators);
- break;
- }
- break;
- }
- }
- int count = (int)validators_count.Get().Votes.Select((p, i) => new
- {
- Count = i,
- Votes = p
- }).Where(p => p.Votes > Fixed8.Zero).ToArray().WeightedFilter(0.25, 0.75, p => p.Votes.GetData(), (p, w) => new
- {
- p.Count,
- Weight = w
- }).WeightedAverage(p => p.Count, p => p.Weight);
- count = Math.Max(count, StandbyValidators.Length);
- HashSet sv = new HashSet(StandbyValidators);
- ECPoint[] pubkeys = validators.Find().Select(p => p.Value).Where(p => (p.Registered && p.Votes > Fixed8.Zero) || sv.Contains(p.PublicKey)).OrderByDescending(p => p.Votes).ThenBy(p => p.PublicKey).Select(p => p.PublicKey).Take(count).ToArray();
- IEnumerable result;
- if (pubkeys.Length == count)
- {
- result = pubkeys;
- }
- else
- {
- HashSet hashSet = new HashSet(pubkeys);
- for (int i = 0; i < StandbyValidators.Length && hashSet.Count < count; i++)
- hashSet.Add(StandbyValidators[i]);
- result = hashSet;
- }
- return result.OrderBy(p => p);
- }
-
- ///
- /// 根据指定的散列值,返回下一个区块的信息
- ///
- /// 散列值
- /// 返回下一个区块的信息>
- public abstract Block GetNextBlock(UInt256 hash);
-
- ///
- /// 根据指定的散列值,返回下一个区块的散列值
- ///
- /// 散列值
- /// 返回下一个区块的散列值
- public abstract UInt256 GetNextBlockHash(UInt256 hash);
-
- byte[] IScriptTable.GetScript(byte[] script_hash)
- {
- return GetContract(new UInt160(script_hash)).Script;
- }
-
- public abstract StorageItem GetStorageItem(StorageKey key);
-
- ///
- /// 根据指定的区块高度,返回对应区块及之前所有区块中包含的系统费用的总量
- ///
- /// 区块高度
- /// 返回对应的系统费用的总量
- public virtual long GetSysFeeAmount(uint height)
- {
- return GetSysFeeAmount(GetBlockHash(height));
- }
-
- ///
- /// 根据指定的区块散列值,返回对应区块及之前所有区块中包含的系统费用的总量
- ///
- /// 散列值
- /// 返回系统费用的总量
- public abstract long GetSysFeeAmount(UInt256 hash);
-
- ///
- /// 根据指定的散列值,返回对应的交易信息
- ///
- /// 散列值
- /// 返回对应的交易信息
- public Transaction GetTransaction(UInt256 hash)
- {
- return GetTransaction(hash, out _);
- }
-
- ///
- /// 根据指定的散列值,返回对应的交易信息与该交易所在区块的高度
- ///
- /// 交易散列值
- /// 返回该交易所在区块的高度
- /// 返回对应的交易信息
- public abstract Transaction GetTransaction(UInt256 hash, out int height);
-
- public abstract Dictionary GetUnclaimed(UInt256 hash);
-
- ///
- /// 根据指定的散列值和索引,获取对应的未花费的资产
- ///
- /// 交易散列值
- /// 输出的索引
- /// 返回一个交易输出,表示一个未花费的资产
- public abstract TransactionOutput GetUnspent(UInt256 hash, ushort index);
-
- public abstract IEnumerable GetUnspent(UInt256 hash);
-
- ///
- /// 判断交易是否双花
- ///
- /// 交易
- /// 返回交易是否双花
- public abstract bool IsDoubleSpend(Transaction tx);
-
- ///
- /// 当区块被写入到硬盘后调用
- ///
- /// 区块
- protected void OnPersistCompleted(Block block)
- {
- lock (_validators)
- {
- _validators.Clear();
- }
- PersistCompleted?.Invoke(this, block);
- }
-
- protected void ProcessAccountStateDescriptor(StateDescriptor descriptor, DataCache accounts, DataCache validators, MetaDataCache validators_count)
- {
- UInt160 hash = new UInt160(descriptor.Key);
- AccountState account = accounts.GetAndChange(hash, () => new AccountState(hash));
- switch (descriptor.Field)
- {
- case "Votes":
- Fixed8 balance = account.GetBalance(GoverningToken.Hash);
- foreach (ECPoint pubkey in account.Votes)
- {
- ValidatorState validator = validators.GetAndChange(pubkey);
- validator.Votes -= balance;
- if (!validator.Registered && validator.Votes.Equals(Fixed8.Zero))
- validators.Delete(pubkey);
- }
- ECPoint[] votes = descriptor.Value.AsSerializableArray().Distinct().ToArray();
- if (votes.Length != account.Votes.Length)
- {
- ValidatorsCountState count_state = validators_count.GetAndChange();
- if (account.Votes.Length > 0)
- count_state.Votes[account.Votes.Length - 1] -= balance;
- if (votes.Length > 0)
- count_state.Votes[votes.Length - 1] += balance;
- }
- account.Votes = votes;
- foreach (ECPoint pubkey in account.Votes)
- validators.GetAndChange(pubkey, () => new ValidatorState(pubkey)).Votes += balance;
- break;
- }
- }
-
- protected void ProcessValidatorStateDescriptor(StateDescriptor descriptor, DataCache validators)
- {
- ECPoint pubkey = ECPoint.DecodePoint(descriptor.Key, ECCurve.Secp256r1);
- ValidatorState validator = validators.GetAndChange(pubkey, () => new ValidatorState(pubkey));
- switch (descriptor.Field)
- {
- case "Registered":
- validator.Registered = BitConverter.ToBoolean(descriptor.Value, 0);
- break;
- }
- }
-
- ///
- /// 注册默认的区块链实例
- ///
- /// 区块链实例
- /// 返回注册后的区块链实例
- public static Blockchain RegisterBlockchain(Blockchain blockchain)
- {
- if (Default != null) Default.Dispose();
- Default = blockchain ?? throw new ArgumentNullException();
- return blockchain;
- }
- }
-}
diff --git a/neo/Core/ClaimTransaction.cs b/neo/Core/ClaimTransaction.cs
deleted file mode 100644
index d544c88d95..0000000000
--- a/neo/Core/ClaimTransaction.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-using Neo.IO;
-using Neo.IO.Json;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- public class ClaimTransaction : Transaction
- {
- public CoinReference[] Claims;
-
- public override Fixed8 NetworkFee => Fixed8.Zero;
-
- public override int Size => base.Size + Claims.GetVarSize();
-
- public ClaimTransaction()
- : base(TransactionType.ClaimTransaction)
- {
- }
-
- ///
- /// 反序列化交易中的额外数据
- ///
- /// 数据来源
- protected override void DeserializeExclusiveData(BinaryReader reader)
- {
- if (Version != 0) throw new FormatException();
- Claims = reader.ReadSerializableArray();
- if (Claims.Length == 0) throw new FormatException();
- }
-
- ///
- /// 获得需要校验的脚本Hash
- ///
- /// 返回需要校验的脚本Hash
- public override UInt160[] GetScriptHashesForVerifying()
- {
- HashSet hashes = new HashSet(base.GetScriptHashesForVerifying());
- foreach (var group in Claims.GroupBy(p => p.PrevHash))
- {
- Transaction tx = Blockchain.Default.GetTransaction(group.Key);
- if (tx == null) throw new InvalidOperationException();
- foreach (CoinReference claim in group)
- {
- if (tx.Outputs.Length <= claim.PrevIndex) throw new InvalidOperationException();
- hashes.Add(tx.Outputs[claim.PrevIndex].ScriptHash);
- }
- }
- return hashes.OrderBy(p => p).ToArray();
- }
-
- ///
- /// 序列化交易中的额外数据
- ///
- /// 存放序列化后的结果
- protected override void SerializeExclusiveData(BinaryWriter writer)
- {
- writer.Write(Claims);
- }
-
- ///
- /// 变成json对象
- ///
- /// 返回json对象
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["claims"] = new JArray(Claims.Select(p => p.ToJson()).ToArray());
- return json;
- }
-
- ///
- /// 验证交易
- ///
- /// 返回验证结果
- public override bool Verify(IEnumerable mempool)
- {
- if (!base.Verify(mempool)) return false;
- if (Claims.Length != Claims.Distinct().Count())
- return false;
- if (mempool.OfType().Where(p => p != this).SelectMany(p => p.Claims).Intersect(Claims).Count() > 0)
- return false;
- TransactionResult result = GetTransactionResults().FirstOrDefault(p => p.AssetId == Blockchain.UtilityToken.Hash);
- if (result == null || result.Amount > Fixed8.Zero) return false;
- try
- {
- return Blockchain.CalculateBonus(Claims, false) == -result.Amount;
- }
- catch (ArgumentException)
- {
- return false;
- }
- catch (NotSupportedException)
- {
- return false;
- }
- }
- }
-}
diff --git a/neo/Core/CoinReference.cs b/neo/Core/CoinReference.cs
deleted file mode 100644
index 4145fbe20e..0000000000
--- a/neo/Core/CoinReference.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.VM;
-using System;
-using System.IO;
-
-namespace Neo.Core
-{
- ///
- /// 交易输入
- ///
- public class CoinReference : IEquatable, IInteropInterface, ISerializable
- {
- ///
- /// 引用交易的散列值
- ///
- public UInt256 PrevHash;
- ///
- /// 引用交易输出的索引
- ///
- public ushort PrevIndex;
-
- public int Size => PrevHash.Size + sizeof(ushort);
-
- void ISerializable.Deserialize(BinaryReader reader)
- {
- PrevHash = reader.ReadSerializable();
- PrevIndex = reader.ReadUInt16();
- }
-
- ///
- /// 比较当前对象与指定对象是否相等
- ///
- /// 要比较的对象
- /// 返回对象是否相等
- public bool Equals(CoinReference other)
- {
- if (ReferenceEquals(this, other)) return true;
- if (ReferenceEquals(null, other)) return false;
- return PrevHash.Equals(other.PrevHash) && PrevIndex.Equals(other.PrevIndex);
- }
-
- ///
- /// 比较当前对象与指定对象是否相等
- ///
- /// 要比较的对象
- /// 返回对象是否相等
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(this, obj)) return true;
- if (ReferenceEquals(null, obj)) return false;
- if (!(obj is CoinReference)) return false;
- return Equals((CoinReference)obj);
- }
-
- ///
- /// 获得对象的HashCode
- ///
- /// 返回对象的HashCode
- public override int GetHashCode()
- {
- return PrevHash.GetHashCode() + PrevIndex.GetHashCode();
- }
-
- void ISerializable.Serialize(BinaryWriter writer)
- {
- writer.Write(PrevHash);
- writer.Write(PrevIndex);
- }
-
- ///
- /// 将交易输入转变为json对象
- ///
- /// 返回json对象
- public JObject ToJson()
- {
- JObject json = new JObject();
- json["txid"] = PrevHash.ToString();
- json["vout"] = PrevIndex;
- return json;
- }
- }
-}
diff --git a/neo/Core/CoinState.cs b/neo/Core/CoinState.cs
deleted file mode 100644
index 85300e5763..0000000000
--- a/neo/Core/CoinState.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-
-namespace Neo.Core
-{
- [Flags]
- public enum CoinState : byte
- {
- Unconfirmed = 0,
-
- Confirmed = 1 << 0,
- Spent = 1 << 1,
- //Vote = 1 << 2,
- Claimed = 1 << 3,
- //Locked = 1 << 4,
- Frozen = 1 << 5,
- //WatchOnly = 1 << 6,
- }
-}
diff --git a/neo/Core/ContractPropertyState.cs b/neo/Core/ContractPropertyState.cs
deleted file mode 100644
index 25a675a279..0000000000
--- a/neo/Core/ContractPropertyState.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-
-namespace Neo.Core
-{
- [Flags]
- public enum ContractPropertyState : byte
- {
- NoProperty = 0,
-
- HasStorage = 1 << 0,
- HasDynamicInvoke = 1 << 1,
- }
-}
diff --git a/neo/Core/ContractState.cs b/neo/Core/ContractState.cs
deleted file mode 100644
index f2586edae1..0000000000
--- a/neo/Core/ContractState.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.SmartContract;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- public class ContractState : StateBase, ICloneable
- {
- public byte[] Script;
- public ContractParameterType[] ParameterList;
- public ContractParameterType ReturnType;
- public ContractPropertyState ContractProperties;
- public string Name;
- public string CodeVersion;
- public string Author;
- public string Email;
- public string Description;
-
-
- public bool HasStorage => ContractProperties.HasFlag(ContractPropertyState.HasStorage);
-
- public bool HasDynamicInvoke => ContractProperties.HasFlag(ContractPropertyState.HasDynamicInvoke);
-
- private UInt160 _scriptHash;
- public UInt160 ScriptHash
- {
- get
- {
- if (_scriptHash == null)
- {
- _scriptHash = Script.ToScriptHash();
- }
- return _scriptHash;
- }
- }
-
- public override int Size => base.Size + Script.GetVarSize() + ParameterList.GetVarSize() + sizeof(ContractParameterType) + sizeof(bool) + Name.GetVarSize() + CodeVersion.GetVarSize() + Author.GetVarSize() + Email.GetVarSize() + Description.GetVarSize();
-
- ContractState ICloneable.Clone()
- {
- return new ContractState
- {
- Script = Script,
- ParameterList = ParameterList,
- ReturnType = ReturnType,
- ContractProperties = ContractProperties,
- Name = Name,
- CodeVersion = CodeVersion,
- Author = Author,
- Email = Email,
- Description = Description
- };
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- Script = reader.ReadVarBytes();
- ParameterList = reader.ReadVarBytes().Select(p => (ContractParameterType)p).ToArray();
- ReturnType = (ContractParameterType)reader.ReadByte();
- ContractProperties = (ContractPropertyState)reader.ReadByte();
- Name = reader.ReadVarString();
- CodeVersion = reader.ReadVarString();
- Author = reader.ReadVarString();
- Email = reader.ReadVarString();
- Description = reader.ReadVarString();
- }
-
- void ICloneable.FromReplica(ContractState replica)
- {
- Script = replica.Script;
- ParameterList = replica.ParameterList;
- ReturnType = replica.ReturnType;
- ContractProperties = replica.ContractProperties;
- Name = replica.Name;
- CodeVersion = replica.CodeVersion;
- Author = replica.Author;
- Email = replica.Email;
- Description = replica.Description;
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.WriteVarBytes(Script);
- writer.WriteVarBytes(ParameterList.Cast().ToArray());
- writer.Write((byte)ReturnType);
- writer.Write((byte)ContractProperties);
- writer.WriteVarString(Name);
- writer.WriteVarString(CodeVersion);
- writer.WriteVarString(Author);
- writer.WriteVarString(Email);
- writer.WriteVarString(Description);
- }
-
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["hash"] = ScriptHash.ToString();
- json["script"] = Script.ToHexString();
- json["parameters"] = new JArray(ParameterList.Select(p => (JObject)p));
- json["returntype"] = ReturnType;
- json["name"] = Name;
- json["code_version"] = CodeVersion;
- json["author"] = Author;
- json["email"] = Email;
- json["description"] = Description;
- json["properties"] = new JObject();
- json["properties"]["storage"] = HasStorage;
- json["properties"]["dynamic_invoke"] = HasDynamicInvoke;
- return json;
- }
- }
-}
diff --git a/neo/Core/ContractTransaction.cs b/neo/Core/ContractTransaction.cs
deleted file mode 100644
index 252976fd69..0000000000
--- a/neo/Core/ContractTransaction.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using System.IO;
-
-namespace Neo.Core
-{
- ///
- /// 合约交易,这是最常用的一种交易
- ///
- public class ContractTransaction : Transaction
- {
- public ContractTransaction()
- : base(TransactionType.ContractTransaction)
- {
- }
-
- protected override void DeserializeExclusiveData(BinaryReader reader)
- {
- if (Version != 0) throw new FormatException();
- }
- }
-}
diff --git a/neo/Core/EnrollmentTransaction.cs b/neo/Core/EnrollmentTransaction.cs
deleted file mode 100644
index 89af83b426..0000000000
--- a/neo/Core/EnrollmentTransaction.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.SmartContract;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- [Obsolete]
- public class EnrollmentTransaction : Transaction
- {
- ///
- /// 记账人的公钥
- ///
- public ECPoint PublicKey;
-
- private UInt160 _script_hash = null;
- private UInt160 ScriptHash
- {
- get
- {
- if (_script_hash == null)
- {
- _script_hash = Contract.CreateSignatureRedeemScript(PublicKey).ToScriptHash();
- }
- return _script_hash;
- }
- }
-
- public override int Size => base.Size + PublicKey.Size;
-
- public EnrollmentTransaction()
- : base(TransactionType.EnrollmentTransaction)
- {
- }
-
- ///
- /// 序列化交易中的额外数据
- ///
- /// 数据来源
- protected override void DeserializeExclusiveData(BinaryReader reader)
- {
- if (Version != 0) throw new FormatException();
- PublicKey = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1);
- }
-
- ///
- /// 获取需要校验的脚本Hash
- ///
- /// 返回需要校验的脚本Hash
- public override UInt160[] GetScriptHashesForVerifying()
- {
- return base.GetScriptHashesForVerifying().Union(new UInt160[] { ScriptHash }).OrderBy(p => p).ToArray();
- }
-
- ///
- /// 序列化交易中的额外数据
- ///
- /// 存放序列化后的结果
- protected override void SerializeExclusiveData(BinaryWriter writer)
- {
- writer.Write(PublicKey);
- }
-
- ///
- /// 变成json对象
- ///
- /// 返回json对象
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["pubkey"] = PublicKey.ToString();
- return json;
- }
-
- public override bool Verify(IEnumerable mempool)
- {
- return false;
- }
- }
-}
diff --git a/neo/Core/Header.cs b/neo/Core/Header.cs
deleted file mode 100644
index 096707fd82..0000000000
--- a/neo/Core/Header.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using Neo.IO;
-using Neo.VM;
-using System;
-using System.IO;
-
-namespace Neo.Core
-{
- public class Header : BlockBase, IEquatable
- {
- public override int Size => base.Size + 1;
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- if (reader.ReadByte() != 0) throw new FormatException();
- }
-
- public bool Equals(Header other)
- {
- if (ReferenceEquals(other, null)) return false;
- if (ReferenceEquals(other, this)) return true;
- return Hash.Equals(other.Hash);
- }
-
- public override bool Equals(object obj)
- {
- return Equals(obj as Header);
- }
-
- public static Header FromTrimmedData(byte[] data, int index)
- {
- Header header = new Header();
- using (MemoryStream ms = new MemoryStream(data, index, data.Length - index, false))
- using (BinaryReader reader = new BinaryReader(ms))
- {
- ((IVerifiable)header).DeserializeUnsigned(reader);
- reader.ReadByte(); header.Script = reader.ReadSerializable();
- }
- return header;
- }
-
- public override int GetHashCode()
- {
- return Hash.GetHashCode();
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write((byte)0);
- }
- }
-}
diff --git a/neo/Core/Helper.cs b/neo/Core/Helper.cs
deleted file mode 100644
index 1c35f838fc..0000000000
--- a/neo/Core/Helper.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using Neo.Cryptography;
-using Neo.SmartContract;
-using Neo.VM;
-using Neo.Wallets;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- ///
- /// 包含一系列签名与验证的扩展方法
- ///
- public static class Helper
- {
- public static byte[] GetHashData(this IVerifiable verifiable)
- {
- using (MemoryStream ms = new MemoryStream())
- using (BinaryWriter writer = new BinaryWriter(ms))
- {
- verifiable.SerializeUnsigned(writer);
- writer.Flush();
- return ms.ToArray();
- }
- }
-
- ///
- /// 根据传入的账户信息,对可签名的对象进行签名
- ///
- /// 要签名的数据
- /// 用于签名的账户
- /// 返回签名后的结果
- public static byte[] Sign(this IVerifiable verifiable, KeyPair key)
- {
- using (key.Decrypt())
- {
- return Crypto.Default.Sign(verifiable.GetHashData(), key.PrivateKey, key.PublicKey.EncodePoint(false).Skip(1).ToArray());
- }
- }
-
- public static UInt160 ToScriptHash(this byte[] script)
- {
- return new UInt160(Crypto.Default.Hash160(script));
- }
-
- internal static bool VerifyScripts(this IVerifiable verifiable)
- {
- UInt160[] hashes;
- try
- {
- hashes = verifiable.GetScriptHashesForVerifying();
- }
- catch (InvalidOperationException)
- {
- return false;
- }
- if (hashes.Length != verifiable.Scripts.Length) return false;
- for (int i = 0; i < hashes.Length; i++)
- {
- byte[] verification = verifiable.Scripts[i].VerificationScript;
- if (verification.Length == 0)
- {
- using (ScriptBuilder sb = new ScriptBuilder())
- {
- sb.EmitAppCall(hashes[i].ToArray());
- verification = sb.ToArray();
- }
- }
- else
- {
- if (hashes[i] != verifiable.Scripts[i].ScriptHash) return false;
- }
- using (StateReader service = new StateReader())
- {
- ApplicationEngine engine = new ApplicationEngine(TriggerType.Verification, verifiable, Blockchain.Default, service, Fixed8.Zero);
- engine.LoadScript(verification, false);
- engine.LoadScript(verifiable.Scripts[i].InvocationScript, true);
- if (!engine.Execute()) return false;
- if (engine.EvaluationStack.Count != 1 || !engine.EvaluationStack.Pop().GetBoolean()) return false;
- }
- }
- return true;
- }
- }
-}
diff --git a/neo/Core/IVerifiable.cs b/neo/Core/IVerifiable.cs
deleted file mode 100644
index dcf9fc72b4..0000000000
--- a/neo/Core/IVerifiable.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using Neo.IO;
-using Neo.VM;
-using System.IO;
-
-namespace Neo.Core
-{
- ///
- /// 为需要签名的数据提供一个接口
- ///
- public interface IVerifiable : ISerializable, IScriptContainer
- {
- ///
- /// 用于验证该对象的脚本列表
- ///
- Witness[] Scripts { get; set; }
-
- ///
- /// 反序列化未签名的数据
- ///
- /// 数据来源
- void DeserializeUnsigned(BinaryReader reader);
-
- ///
- /// 获得需要校验的脚本Hash值
- ///
- /// 返回需要校验的脚本Hash值
- UInt160[] GetScriptHashesForVerifying();
-
- ///
- /// 序列化未签名的数据
- ///
- /// 存放序列化后的结果
- void SerializeUnsigned(BinaryWriter writer);
- }
-}
diff --git a/neo/Core/InvocationTransaction.cs b/neo/Core/InvocationTransaction.cs
deleted file mode 100644
index be1d63c27f..0000000000
--- a/neo/Core/InvocationTransaction.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using Neo.IO;
-using Neo.IO.Json;
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Neo.Core
-{
- public class InvocationTransaction : Transaction
- {
- public byte[] Script;
- public Fixed8 Gas;
-
- public override int Size => base.Size + Script.GetVarSize();
-
- public override Fixed8 SystemFee => Gas;
-
- public InvocationTransaction()
- : base(TransactionType.InvocationTransaction)
- {
- }
-
- protected override void DeserializeExclusiveData(BinaryReader reader)
- {
- if (Version > 1) throw new FormatException();
- Script = reader.ReadVarBytes(65536);
- if (Script.Length == 0) throw new FormatException();
- if (Version >= 1)
- {
- Gas = reader.ReadSerializable();
- if (Gas < Fixed8.Zero) throw new FormatException();
- }
- else
- {
- Gas = Fixed8.Zero;
- }
- }
-
- public static Fixed8 GetGas(Fixed8 consumed)
- {
- Fixed8 gas = consumed - Fixed8.FromDecimal(10);
- if (gas <= Fixed8.Zero) return Fixed8.Zero;
- return gas.Ceiling();
- }
-
- protected override void SerializeExclusiveData(BinaryWriter writer)
- {
- writer.WriteVarBytes(Script);
- if (Version >= 1)
- writer.Write(Gas);
- }
-
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["script"] = Script.ToHexString();
- json["gas"] = Gas.ToString();
- return json;
- }
-
- public override bool Verify(IEnumerable mempool)
- {
- if (Gas.GetData() % 100000000 != 0) return false;
- return base.Verify(mempool);
- }
- }
-}
diff --git a/neo/Core/IssueTransaction.cs b/neo/Core/IssueTransaction.cs
deleted file mode 100644
index 60e53c8f2e..0000000000
--- a/neo/Core/IssueTransaction.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- ///
- /// 用于分发资产的特殊交易
- ///
- public class IssueTransaction : Transaction
- {
- ///
- /// 系统费用
- ///
- public override Fixed8 SystemFee
- {
- get
- {
- if (Version >= 1) return Fixed8.Zero;
- if (Outputs.All(p => p.AssetId == Blockchain.GoverningToken.Hash || p.AssetId == Blockchain.UtilityToken.Hash))
- return Fixed8.Zero;
- return base.SystemFee;
- }
- }
-
- public IssueTransaction()
- : base(TransactionType.IssueTransaction)
- {
- }
-
- protected override void DeserializeExclusiveData(BinaryReader reader)
- {
- if (Version > 1) throw new FormatException();
- }
-
- ///
- /// 获取需要校验的脚本散列值
- ///
- /// 返回需要校验的脚本散列值
- public override UInt160[] GetScriptHashesForVerifying()
- {
- HashSet hashes = new HashSet(base.GetScriptHashesForVerifying());
- foreach (TransactionResult result in GetTransactionResults().Where(p => p.Amount < Fixed8.Zero))
- {
- AssetState asset = Blockchain.Default.GetAssetState(result.AssetId);
- if (asset == null) throw new InvalidOperationException();
- hashes.Add(asset.Issuer);
- }
- return hashes.OrderBy(p => p).ToArray();
- }
-
- ///
- /// 验证交易
- ///
- /// 返回验证后的结果
- public override bool Verify(IEnumerable mempool)
- {
- if (!base.Verify(mempool)) return false;
- TransactionResult[] results = GetTransactionResults()?.Where(p => p.Amount < Fixed8.Zero).ToArray();
- if (results == null) return false;
- foreach (TransactionResult r in results)
- {
- AssetState asset = Blockchain.Default.GetAssetState(r.AssetId);
- if (asset == null) return false;
- if (asset.Amount < Fixed8.Zero) continue;
- Fixed8 quantity_issued = asset.Available + mempool.OfType().Where(p => p != this).SelectMany(p => p.Outputs).Where(p => p.AssetId == r.AssetId).Sum(p => p.Value);
- if (asset.Amount - quantity_issued < -r.Amount) return false;
- }
- return true;
- }
- }
-}
diff --git a/neo/Core/MinerTransaction.cs b/neo/Core/MinerTransaction.cs
deleted file mode 100644
index 78cdd8b4a4..0000000000
--- a/neo/Core/MinerTransaction.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using Neo.IO.Json;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- ///
- /// 用于分配字节费的特殊交易
- ///
- public class MinerTransaction : Transaction
- {
- ///
- /// 随机数
- ///
- public uint Nonce;
-
- public override Fixed8 NetworkFee => Fixed8.Zero;
-
- public override int Size => base.Size + sizeof(uint);
-
- public MinerTransaction()
- : base(TransactionType.MinerTransaction)
- {
- }
-
- ///
- /// 反序列化交易中的额外数据
- ///
- /// 数据来源
- protected override void DeserializeExclusiveData(BinaryReader reader)
- {
- if (Version != 0) throw new FormatException();
- this.Nonce = reader.ReadUInt32();
- }
-
- ///
- /// 反序列化进行完毕时触发
- ///
- protected override void OnDeserialized()
- {
- base.OnDeserialized();
- if (Inputs.Length != 0)
- throw new FormatException();
- if (Outputs.Any(p => p.AssetId != Blockchain.UtilityToken.Hash))
- throw new FormatException();
- }
-
- ///
- /// 序列化交易中的额外数据
- ///
- /// 存放序列化后的结果
- protected override void SerializeExclusiveData(BinaryWriter writer)
- {
- writer.Write(Nonce);
- }
-
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["nonce"] = Nonce;
- return json;
- }
- }
-}
diff --git a/neo/Core/PublishTransaction.cs b/neo/Core/PublishTransaction.cs
deleted file mode 100644
index 3826cd3088..0000000000
--- a/neo/Core/PublishTransaction.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.SmartContract;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- [Obsolete]
- public class PublishTransaction : Transaction
- {
- public byte[] Script;
- public ContractParameterType[] ParameterList;
- public ContractParameterType ReturnType;
- public bool NeedStorage;
- public string Name;
- public string CodeVersion;
- public string Author;
- public string Email;
- public string Description;
-
- private UInt160 _scriptHash;
- internal UInt160 ScriptHash
- {
- get
- {
- if (_scriptHash == null)
- {
- _scriptHash = Script.ToScriptHash();
- }
- return _scriptHash;
- }
- }
-
- public override int Size => base.Size + Script.GetVarSize() + ParameterList.GetVarSize() + sizeof(ContractParameterType) + Name.GetVarSize() + CodeVersion.GetVarSize() + Author.GetVarSize() + Email.GetVarSize() + Description.GetVarSize();
-
- public PublishTransaction()
- : base(TransactionType.PublishTransaction)
- {
- }
-
- protected override void DeserializeExclusiveData(BinaryReader reader)
- {
- if (Version > 1) throw new FormatException();
- Script = reader.ReadVarBytes();
- ParameterList = reader.ReadVarBytes().Select(p => (ContractParameterType)p).ToArray();
- ReturnType = (ContractParameterType)reader.ReadByte();
- if (Version >= 1)
- NeedStorage = reader.ReadBoolean();
- else
- NeedStorage = false;
- Name = reader.ReadVarString(252);
- CodeVersion = reader.ReadVarString(252);
- Author = reader.ReadVarString(252);
- Email = reader.ReadVarString(252);
- Description = reader.ReadVarString(65536);
- }
-
- protected override void SerializeExclusiveData(BinaryWriter writer)
- {
- writer.WriteVarBytes(Script);
- writer.WriteVarBytes(ParameterList.Cast().ToArray());
- writer.Write((byte)ReturnType);
- if (Version >= 1) writer.Write(NeedStorage);
- writer.WriteVarString(Name);
- writer.WriteVarString(CodeVersion);
- writer.WriteVarString(Author);
- writer.WriteVarString(Email);
- writer.WriteVarString(Description);
- }
-
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["contract"] = new JObject();
- json["contract"]["code"] = new JObject();
- json["contract"]["code"]["hash"] = ScriptHash.ToString();
- json["contract"]["code"]["script"] = Script.ToHexString();
- json["contract"]["code"]["parameters"] = new JArray(ParameterList.Select(p => (JObject)p));
- json["contract"]["code"]["returntype"] = ReturnType;
- json["contract"]["needstorage"] = NeedStorage;
- json["contract"]["name"] = Name;
- json["contract"]["version"] = CodeVersion;
- json["contract"]["author"] = Author;
- json["contract"]["email"] = Email;
- json["contract"]["description"] = Description;
- return json;
- }
-
- public override bool Verify(IEnumerable mempool)
- {
- return false;
- }
- }
-}
diff --git a/neo/Core/RegisterTransaction.cs b/neo/Core/RegisterTransaction.cs
deleted file mode 100644
index 667df17b1f..0000000000
--- a/neo/Core/RegisterTransaction.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.SmartContract;
-using Neo.Wallets;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- [Obsolete]
- public class RegisterTransaction : Transaction
- {
- ///
- /// 资产类别
- ///
- public AssetType AssetType;
- ///
- /// 资产名称
- ///
- public string Name;
- ///
- /// 发行总量,共有2种模式:
- /// 1. 限量模式:当Amount为正数时,表示当前资产的最大总量为Amount,且不可修改(股权在未来可能会支持扩股或增发,会考虑需要公司签名或一定比例的股东签名认可)。
- /// 2. 不限量模式:当Amount等于-1时,表示当前资产可以由创建者无限量发行。这种模式的自由度最大,但是公信力最低,不建议使用。
- ///
- public Fixed8 Amount;
- public byte Precision;
- ///
- /// 发行者的公钥
- ///
- public ECPoint Owner;
- ///
- /// 资产管理员的合约散列值
- ///
- public UInt160 Admin;
-
- public override int Size => base.Size + sizeof(AssetType) + Name.GetVarSize() + Amount.Size + sizeof(byte) + Owner.Size + Admin.Size;
-
- ///
- /// 系统费用
- ///
- public override Fixed8 SystemFee
- {
- get
- {
- if (AssetType == AssetType.GoverningToken || AssetType == AssetType.UtilityToken)
- return Fixed8.Zero;
- return base.SystemFee;
- }
- }
-
- public RegisterTransaction()
- : base(TransactionType.RegisterTransaction)
- {
- }
-
- ///
- /// 反序列化交易中额外的数据
- ///
- /// 数据来源
- protected override void DeserializeExclusiveData(BinaryReader reader)
- {
- if (Version != 0) throw new FormatException();
- AssetType = (AssetType)reader.ReadByte();
- Name = reader.ReadVarString(1024);
- Amount = reader.ReadSerializable();
- Precision = reader.ReadByte();
- Owner = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1);
- if (Owner.IsInfinity && AssetType != AssetType.GoverningToken && AssetType != AssetType.UtilityToken)
- throw new FormatException();
- Admin = reader.ReadSerializable();
- }
-
- ///
- /// 获取需要校验的脚本Hash值
- ///
- /// 返回需要校验的脚本Hash值
- public override UInt160[] GetScriptHashesForVerifying()
- {
- UInt160 owner = Contract.CreateSignatureRedeemScript(Owner).ToScriptHash();
- return base.GetScriptHashesForVerifying().Union(new[] { owner }).OrderBy(p => p).ToArray();
- }
-
- protected override void OnDeserialized()
- {
- base.OnDeserialized();
- if (AssetType == AssetType.GoverningToken && !Hash.Equals(Blockchain.GoverningToken.Hash))
- throw new FormatException();
- if (AssetType == AssetType.UtilityToken && !Hash.Equals(Blockchain.UtilityToken.Hash))
- throw new FormatException();
- }
-
- ///
- /// 序列化交易中额外的数据
- ///
- /// 存放序列化后的结果
- protected override void SerializeExclusiveData(BinaryWriter writer)
- {
- writer.Write((byte)AssetType);
- writer.WriteVarString(Name);
- writer.Write(Amount);
- writer.Write(Precision);
- writer.Write(Owner);
- writer.Write(Admin);
- }
-
- ///
- /// 变成json对象
- ///
- /// 返回json对象
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["asset"] = new JObject();
- json["asset"]["type"] = AssetType;
- try
- {
- json["asset"]["name"] = Name == "" ? null : JObject.Parse(Name);
- }
- catch (FormatException)
- {
- json["asset"]["name"] = Name;
- }
- json["asset"]["amount"] = Amount.ToString();
- json["asset"]["precision"] = Precision;
- json["asset"]["owner"] = Owner.ToString();
- json["asset"]["admin"] = Wallet.ToAddress(Admin);
- return json;
- }
-
- public override bool Verify(IEnumerable mempool)
- {
- return false;
- }
- }
-}
diff --git a/neo/Core/SpentCoin.cs b/neo/Core/SpentCoin.cs
deleted file mode 100644
index ba6a900aa7..0000000000
--- a/neo/Core/SpentCoin.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Neo.Core
-{
- public class SpentCoin
- {
- public TransactionOutput Output;
- public uint StartHeight;
- public uint EndHeight;
-
- public Fixed8 Value => Output.Value;
- }
-}
diff --git a/neo/Core/SpentCoinState.cs b/neo/Core/SpentCoinState.cs
deleted file mode 100644
index 9f1e8b4049..0000000000
--- a/neo/Core/SpentCoinState.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using Neo.IO;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Neo.Core
-{
- public class SpentCoinState : StateBase, ICloneable
- {
- public UInt256 TransactionHash;
- public uint TransactionHeight;
- public Dictionary Items;
-
- public override int Size => base.Size + TransactionHash.Size + sizeof(uint)
- + IO.Helper.GetVarSize(Items.Count) + Items.Count * (sizeof(ushort) + sizeof(uint));
-
- SpentCoinState ICloneable.Clone()
- {
- return new SpentCoinState
- {
- TransactionHash = TransactionHash,
- TransactionHeight = TransactionHeight,
- Items = new Dictionary(Items)
- };
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- TransactionHash = reader.ReadSerializable();
- TransactionHeight = reader.ReadUInt32();
- int count = (int)reader.ReadVarInt();
- Items = new Dictionary(count);
- for (int i = 0; i < count; i++)
- {
- ushort index = reader.ReadUInt16();
- uint height = reader.ReadUInt32();
- Items.Add(index, height);
- }
- }
-
- void ICloneable.FromReplica(SpentCoinState replica)
- {
- TransactionHash = replica.TransactionHash;
- TransactionHeight = replica.TransactionHeight;
- Items = replica.Items;
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(TransactionHash);
- writer.Write(TransactionHeight);
- writer.WriteVarInt(Items.Count);
- foreach (var pair in Items)
- {
- writer.Write(pair.Key);
- writer.Write(pair.Value);
- }
- }
- }
-}
diff --git a/neo/Core/StateBase.cs b/neo/Core/StateBase.cs
deleted file mode 100644
index ca1bf5b3f0..0000000000
--- a/neo/Core/StateBase.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.VM;
-using System;
-using System.IO;
-
-namespace Neo.Core
-{
- public abstract class StateBase : IInteropInterface, ISerializable
- {
- public const byte StateVersion = 0;
-
- public virtual int Size => sizeof(byte);
-
- public virtual void Deserialize(BinaryReader reader)
- {
- if (reader.ReadByte() != StateVersion) throw new FormatException();
- }
-
- public virtual void Serialize(BinaryWriter writer)
- {
- writer.Write(StateVersion);
- }
-
- public virtual JObject ToJson()
- {
- JObject json = new JObject();
- json["version"] = StateVersion;
- return json;
- }
- }
-}
diff --git a/neo/Core/StateDescriptor.cs b/neo/Core/StateDescriptor.cs
deleted file mode 100644
index 70623423ef..0000000000
--- a/neo/Core/StateDescriptor.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using Neo.IO.Caching;
-using Neo.IO.Json;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- public class StateDescriptor : ISerializable
- {
- public StateType Type;
- public byte[] Key;
- public string Field;
- public byte[] Value;
-
- public int Size => sizeof(StateType) + Key.GetVarSize() + Field.GetVarSize() + Value.GetVarSize();
-
- public Fixed8 SystemFee
- {
- get
- {
- switch (Type)
- {
- case StateType.Validator:
- return GetSystemFee_Validator();
- default:
- return Fixed8.Zero;
- }
- }
- }
-
- private void CheckAccountState()
- {
- if (Key.Length != 20) throw new FormatException();
- if (Field != "Votes") throw new FormatException();
- }
-
- private void CheckValidatorState()
- {
- if (Key.Length != 33) throw new FormatException();
- if (Field != "Registered") throw new FormatException();
- }
-
- void ISerializable.Deserialize(BinaryReader reader)
- {
- Type = (StateType)reader.ReadByte();
- if (!Enum.IsDefined(typeof(StateType), Type))
- throw new FormatException();
- Key = reader.ReadVarBytes(100);
- Field = reader.ReadVarString(32);
- Value = reader.ReadVarBytes(65535);
- switch (Type)
- {
- case StateType.Account:
- CheckAccountState();
- break;
- case StateType.Validator:
- CheckValidatorState();
- break;
- }
- }
-
- private Fixed8 GetSystemFee_Validator()
- {
- switch (Field)
- {
- case "Registered":
- if (Value.Any(p => p != 0))
- return Fixed8.FromDecimal(1000);
- else
- return Fixed8.Zero;
- default:
- throw new InvalidOperationException();
- }
- }
-
- void ISerializable.Serialize(BinaryWriter writer)
- {
- writer.Write((byte)Type);
- writer.WriteVarBytes(Key);
- writer.WriteVarString(Field);
- writer.WriteVarBytes(Value);
- }
-
- public JObject ToJson()
- {
- JObject json = new JObject();
- json["type"] = Type;
- json["key"] = Key.ToHexString();
- json["field"] = Field;
- json["value"] = Value.ToHexString();
- return json;
- }
-
- internal bool Verify()
- {
- switch (Type)
- {
- case StateType.Account:
- return VerifyAccountState();
- case StateType.Validator:
- return VerifyValidatorState();
- default:
- return false;
- }
- }
-
- private bool VerifyAccountState()
- {
- switch (Field)
- {
- case "Votes":
- if (Blockchain.Default == null) return false;
- ECPoint[] pubkeys;
- try
- {
- pubkeys = Value.AsSerializableArray((int)Blockchain.MaxValidators);
- }
- catch (FormatException)
- {
- return false;
- }
- UInt160 hash = new UInt160(Key);
- AccountState account = Blockchain.Default.GetAccountState(hash);
- if (account?.IsFrozen != false) return false;
- if (pubkeys.Length > 0)
- {
- if (account.GetBalance(Blockchain.GoverningToken.Hash).Equals(Fixed8.Zero)) return false;
- HashSet sv = new HashSet(Blockchain.StandbyValidators);
- DataCache validators = Blockchain.Default.GetStates();
- foreach (ECPoint pubkey in pubkeys)
- if (!sv.Contains(pubkey) && validators.TryGet(pubkey)?.Registered != true)
- return false;
- }
- return true;
- default:
- return false;
- }
- }
-
- private bool VerifyValidatorState()
- {
- switch (Field)
- {
- case "Registered":
- return true;
- default:
- return false;
- }
- }
- }
-}
diff --git a/neo/Core/StateTransaction.cs b/neo/Core/StateTransaction.cs
deleted file mode 100644
index 1fc996d351..0000000000
--- a/neo/Core/StateTransaction.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.SmartContract;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- public class StateTransaction : Transaction
- {
- public StateDescriptor[] Descriptors;
-
- public override int Size => base.Size + Descriptors.GetVarSize();
- public override Fixed8 SystemFee => Descriptors.Sum(p => p.SystemFee);
-
- public StateTransaction()
- : base(TransactionType.StateTransaction)
- {
- }
-
- protected override void DeserializeExclusiveData(BinaryReader reader)
- {
- Descriptors = reader.ReadSerializableArray(16);
- }
-
- public override UInt160[] GetScriptHashesForVerifying()
- {
- HashSet hashes = new HashSet(base.GetScriptHashesForVerifying());
- foreach (StateDescriptor descriptor in Descriptors)
- {
- switch (descriptor.Type)
- {
- case StateType.Account:
- hashes.UnionWith(GetScriptHashesForVerifying_Account(descriptor));
- break;
- case StateType.Validator:
- hashes.UnionWith(GetScriptHashesForVerifying_Validator(descriptor));
- break;
- default:
- throw new InvalidOperationException();
- }
- }
- return hashes.OrderBy(p => p).ToArray();
- }
-
- private IEnumerable GetScriptHashesForVerifying_Account(StateDescriptor descriptor)
- {
- switch (descriptor.Field)
- {
- case "Votes":
- yield return new UInt160(descriptor.Key);
- break;
- default:
- throw new InvalidOperationException();
- }
- }
-
- private IEnumerable GetScriptHashesForVerifying_Validator(StateDescriptor descriptor)
- {
- switch (descriptor.Field)
- {
- case "Registered":
- yield return Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(descriptor.Key, ECCurve.Secp256r1)).ToScriptHash();
- break;
- default:
- throw new InvalidOperationException();
- }
- }
-
- protected override void SerializeExclusiveData(BinaryWriter writer)
- {
- writer.Write(Descriptors);
- }
-
- public override JObject ToJson()
- {
- JObject json = base.ToJson();
- json["descriptors"] = new JArray(Descriptors.Select(p => p.ToJson()));
- return json;
- }
-
- public override bool Verify(IEnumerable mempool)
- {
- foreach (StateDescriptor descriptor in Descriptors)
- if (!descriptor.Verify())
- return false;
- return base.Verify(mempool);
- }
- }
-}
diff --git a/neo/Core/StateType.cs b/neo/Core/StateType.cs
deleted file mode 100644
index e49cad623a..0000000000
--- a/neo/Core/StateType.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Neo.Core
-{
- public enum StateType : byte
- {
- Account = 0x40,
- Validator = 0x48
- }
-}
diff --git a/neo/Core/StorageItem.cs b/neo/Core/StorageItem.cs
deleted file mode 100644
index 257dbf936b..0000000000
--- a/neo/Core/StorageItem.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Neo.IO;
-using System.IO;
-
-namespace Neo.Core
-{
- public class StorageItem : StateBase, ICloneable
- {
- public byte[] Value;
-
- public override int Size => base.Size + Value.GetVarSize();
-
- StorageItem ICloneable.Clone()
- {
- return new StorageItem
- {
- Value = Value
- };
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- Value = reader.ReadVarBytes();
- }
-
- void ICloneable.FromReplica(StorageItem replica)
- {
- Value = replica.Value;
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.WriteVarBytes(Value);
- }
- }
-}
diff --git a/neo/Core/StorageKey.cs b/neo/Core/StorageKey.cs
deleted file mode 100644
index 3babef23c3..0000000000
--- a/neo/Core/StorageKey.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using Neo.Cryptography;
-using Neo.IO;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- public class StorageKey : IEquatable, ISerializable
- {
- public UInt160 ScriptHash;
- public byte[] Key;
-
- int ISerializable.Size => ScriptHash.Size + Key.GetVarSize();
-
- void ISerializable.Deserialize(BinaryReader reader)
- {
- ScriptHash = reader.ReadSerializable();
- Key = reader.ReadVarBytes();
- }
-
- public bool Equals(StorageKey other)
- {
- if (ReferenceEquals(other, null))
- return false;
- if (ReferenceEquals(this, other))
- return true;
- return ScriptHash.Equals(other.ScriptHash) && Key.SequenceEqual(other.Key);
- }
-
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(obj, null)) return false;
- if (!(obj is StorageKey)) return false;
- return Equals((StorageKey)obj);
- }
-
- public override int GetHashCode()
- {
- return ScriptHash.GetHashCode() + (int)Key.Murmur32(0);
- }
-
- void ISerializable.Serialize(BinaryWriter writer)
- {
- writer.Write(ScriptHash);
- writer.WriteVarBytes(Key);
- }
- }
-}
diff --git a/neo/Core/Transaction.cs b/neo/Core/Transaction.cs
deleted file mode 100644
index 5fce0a3144..0000000000
--- a/neo/Core/Transaction.cs
+++ /dev/null
@@ -1,380 +0,0 @@
-using Neo.Cryptography;
-using Neo.IO;
-using Neo.IO.Caching;
-using Neo.IO.Json;
-using Neo.Network;
-using Neo.VM;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-
-namespace Neo.Core
-{
- ///
- /// 一切交易的基类
- ///
- public abstract class Transaction : IEquatable, IInventory
- {
- ///
- /// Maximum number of attributes that can be contained within a transaction
- ///
- private const int MaxTransactionAttributes = 16;
-
- ///
- /// Reflection cache for TransactionType
- ///
- private static ReflectionCache ReflectionCache = ReflectionCache.CreateFromEnum();
-
- ///
- /// 交易类型
- ///
- public readonly TransactionType Type;
- ///
- /// 版本
- ///
- public byte Version;
- ///
- /// 该交易所具备的额外特性
- ///
- public TransactionAttribute[] Attributes;
- ///
- /// 输入列表
- ///
- public CoinReference[] Inputs;
- ///
- /// 输出列表
- ///
- public TransactionOutput[] Outputs;
- ///
- /// 用于验证该交易的脚本列表
- ///
- public Witness[] Scripts { get; set; }
-
- private UInt256 _hash = null;
- public UInt256 Hash
- {
- get
- {
- if (_hash == null)
- {
- _hash = new UInt256(Crypto.Default.Hash256(this.GetHashData()));
- }
- return _hash;
- }
- }
-
- ///
- /// 清单类型
- ///
- InventoryType IInventory.InventoryType => InventoryType.TX;
-
- private Fixed8 _network_fee = -Fixed8.Satoshi;
- public virtual Fixed8 NetworkFee
- {
- get
- {
- if (_network_fee == -Fixed8.Satoshi)
- {
- Fixed8 input = References.Values.Where(p => p.AssetId.Equals(Blockchain.UtilityToken.Hash)).Sum(p => p.Value);
- Fixed8 output = Outputs.Where(p => p.AssetId.Equals(Blockchain.UtilityToken.Hash)).Sum(p => p.Value);
- _network_fee = input - output - SystemFee;
- }
- return _network_fee;
- }
- }
-
- private IReadOnlyDictionary _references;
- ///
- /// 每一个交易输入所引用的交易输出
- ///
- public IReadOnlyDictionary References
- {
- get
- {
- if (_references == null)
- {
- Dictionary dictionary = new Dictionary();
- foreach (var group in Inputs.GroupBy(p => p.PrevHash))
- {
- Transaction tx = Blockchain.Default.GetTransaction(group.Key);
- if (tx == null) return null;
- foreach (var reference in group.Select(p => new
- {
- Input = p,
- Output = tx.Outputs[p.PrevIndex]
- }))
- {
- dictionary.Add(reference.Input, reference.Output);
- }
- }
- _references = dictionary;
- }
- return _references;
- }
- }
-
- public virtual int Size => sizeof(TransactionType) + sizeof(byte) + Attributes.GetVarSize() + Inputs.GetVarSize() + Outputs.GetVarSize() + Scripts.GetVarSize();
-
- ///
- /// 系统费用
- ///
- public virtual Fixed8 SystemFee => Settings.Default.SystemFee.TryGetValue(Type, out Fixed8 fee) ? fee : Fixed8.Zero;
-
- ///
- /// 用指定的类型初始化Transaction对象
- ///
- /// 交易类型
- protected Transaction(TransactionType type)
- {
- this.Type = type;
- }
-
- ///
- /// 反序列化
- ///
- /// 数据来源
- void ISerializable.Deserialize(BinaryReader reader)
- {
- ((IVerifiable)this).DeserializeUnsigned(reader);
- Scripts = reader.ReadSerializableArray();
- OnDeserialized();
- }
-
- ///
- /// 反序列化交易中的额外数据
- ///
- /// 数据来源
- protected virtual void DeserializeExclusiveData(BinaryReader reader)
- {
- }
-
- ///
- /// 从指定的字节数组反序列化一笔交易
- ///
- /// 字节数组
- /// 偏移量,反序列化从该偏移量处开始
- /// 返回反序列化后的结果
- public static Transaction DeserializeFrom(byte[] value, int offset = 0)
- {
- using (MemoryStream ms = new MemoryStream(value, offset, value.Length - offset, false))
- using (BinaryReader reader = new BinaryReader(ms, Encoding.UTF8))
- {
- return DeserializeFrom(reader);
- }
- }
-
- ///
- /// 反序列化
- ///
- /// 数据来源
- /// 返回反序列化后的结果
- internal static Transaction DeserializeFrom(BinaryReader reader)
- {
- // Looking for type in reflection cache
- Transaction transaction = ReflectionCache.CreateInstance(reader.ReadByte());
- if (transaction == null) throw new FormatException();
-
- transaction.DeserializeUnsignedWithoutType(reader);
- transaction.Scripts = reader.ReadSerializableArray();
- transaction.OnDeserialized();
- return transaction;
- }
-
- void IVerifiable.DeserializeUnsigned(BinaryReader reader)
- {
- if ((TransactionType)reader.ReadByte() != Type)
- throw new FormatException();
- DeserializeUnsignedWithoutType(reader);
- }
-
- private void DeserializeUnsignedWithoutType(BinaryReader reader)
- {
- Version = reader.ReadByte();
- DeserializeExclusiveData(reader);
- Attributes = reader.ReadSerializableArray(MaxTransactionAttributes);
- Inputs = reader.ReadSerializableArray();
- Outputs = reader.ReadSerializableArray(ushort.MaxValue + 1);
- }
-
- public bool Equals(Transaction other)
- {
- if (ReferenceEquals(null, other)) return false;
- if (ReferenceEquals(this, other)) return true;
- return Hash.Equals(other.Hash);
- }
-
- public override bool Equals(object obj)
- {
- return Equals(obj as Transaction);
- }
-
- public override int GetHashCode()
- {
- return Hash.GetHashCode();
- }
-
- byte[] IScriptContainer.GetMessage()
- {
- return this.GetHashData();
- }
-
- ///
- /// 获取需要校验的脚本散列值
- ///
- /// 返回需要校验的脚本散列值
- public virtual UInt160[] GetScriptHashesForVerifying()
- {
- if (References == null) throw new InvalidOperationException();
- HashSet hashes = new HashSet(Inputs.Select(p => References[p].ScriptHash));
- hashes.UnionWith(Attributes.Where(p => p.Usage == TransactionAttributeUsage.Script).Select(p => new UInt160(p.Data)));
- foreach (var group in Outputs.GroupBy(p => p.AssetId))
- {
- AssetState asset = Blockchain.Default.GetAssetState(group.Key);
- if (asset == null) throw new InvalidOperationException();
- if (asset.AssetType.HasFlag(AssetType.DutyFlag))
- {
- hashes.UnionWith(group.Select(p => p.ScriptHash));
- }
- }
- return hashes.OrderBy(p => p).ToArray();
- }
-
- ///
- /// 获取交易后各资产的变化量
- ///
- /// 返回交易后各资产的变化量
- public IEnumerable GetTransactionResults()
- {
- if (References == null) return null;
- return References.Values.Select(p => new
- {
- AssetId = p.AssetId,
- Value = p.Value
- }).Concat(Outputs.Select(p => new
- {
- AssetId = p.AssetId,
- Value = -p.Value
- })).GroupBy(p => p.AssetId, (k, g) => new TransactionResult
- {
- AssetId = k,
- Amount = g.Sum(p => p.Value)
- }).Where(p => p.Amount != Fixed8.Zero);
- }
-
- ///
- /// 通知子类反序列化完毕
- ///
- protected virtual void OnDeserialized()
- {
- }
-
- ///
- /// 序列化
- ///
- /// 存放序列化后的结果
- void ISerializable.Serialize(BinaryWriter writer)
- {
- ((IVerifiable)this).SerializeUnsigned(writer);
- writer.Write(Scripts);
- }
-
- ///
- /// 序列化交易中的额外数据
- ///
- /// 存放序列化后的结果
- protected virtual void SerializeExclusiveData(BinaryWriter writer)
- {
- }
-
- void IVerifiable.SerializeUnsigned(BinaryWriter writer)
- {
- writer.Write((byte)Type);
- writer.Write(Version);
- SerializeExclusiveData(writer);
- writer.Write(Attributes);
- writer.Write(Inputs);
- writer.Write(Outputs);
- }
-
- ///
- /// 变成json对象
- ///
- /// 返回json对象
- public virtual JObject ToJson()
- {
- JObject json = new JObject();
- json["txid"] = Hash.ToString();
- json["size"] = Size;
- json["type"] = Type;
- json["version"] = Version;
- json["attributes"] = Attributes.Select(p => p.ToJson()).ToArray();
- json["vin"] = Inputs.Select(p => p.ToJson()).ToArray();
- json["vout"] = Outputs.Select((p, i) => p.ToJson((ushort)i)).ToArray();
- json["sys_fee"] = SystemFee.ToString();
- json["net_fee"] = NetworkFee.ToString();
- json["scripts"] = Scripts.Select(p => p.ToJson()).ToArray();
- return json;
- }
-
- bool IInventory.Verify()
- {
- return Verify(Enumerable.Empty());
- }
-
- ///
- /// 验证交易
- ///
- /// 返回验证的结果
- public virtual bool Verify(IEnumerable mempool)
- {
- for (int i = 1; i < Inputs.Length; i++)
- for (int j = 0; j < i; j++)
- if (Inputs[i].PrevHash == Inputs[j].PrevHash && Inputs[i].PrevIndex == Inputs[j].PrevIndex)
- return false;
- if (mempool.Where(p => p != this).SelectMany(p => p.Inputs).Intersect(Inputs).Count() > 0)
- return false;
- if (Blockchain.Default.IsDoubleSpend(this))
- return false;
- foreach (var group in Outputs.GroupBy(p => p.AssetId))
- {
- AssetState asset = Blockchain.Default.GetAssetState(group.Key);
- if (asset == null) return false;
- if (asset.Expiration <= Blockchain.Default.Height + 1 && asset.AssetType != AssetType.GoverningToken && asset.AssetType != AssetType.UtilityToken)
- return false;
- foreach (TransactionOutput output in group)
- if (output.Value.GetData() % (long)Math.Pow(10, 8 - asset.Precision) != 0)
- return false;
- }
- TransactionResult[] results = GetTransactionResults()?.ToArray();
- if (results == null) return false;
- TransactionResult[] results_destroy = results.Where(p => p.Amount > Fixed8.Zero).ToArray();
- if (results_destroy.Length > 1) return false;
- if (results_destroy.Length == 1 && results_destroy[0].AssetId != Blockchain.UtilityToken.Hash)
- return false;
- if (SystemFee > Fixed8.Zero && (results_destroy.Length == 0 || results_destroy[0].Amount < SystemFee))
- return false;
- TransactionResult[] results_issue = results.Where(p => p.Amount < Fixed8.Zero).ToArray();
- switch (Type)
- {
- case TransactionType.MinerTransaction:
- case TransactionType.ClaimTransaction:
- if (results_issue.Any(p => p.AssetId != Blockchain.UtilityToken.Hash))
- return false;
- break;
- case TransactionType.IssueTransaction:
- if (results_issue.Any(p => p.AssetId == Blockchain.UtilityToken.Hash))
- return false;
- break;
- default:
- if (results_issue.Length > 0)
- return false;
- break;
- }
- if (Attributes.Count(p => p.Usage == TransactionAttributeUsage.ECDH02 || p.Usage == TransactionAttributeUsage.ECDH03) > 1)
- return false;
- return this.VerifyScripts();
- }
- }
-}
diff --git a/neo/Core/TransactionAttribute.cs b/neo/Core/TransactionAttribute.cs
deleted file mode 100644
index 2cc04194d4..0000000000
--- a/neo/Core/TransactionAttribute.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.VM;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- ///
- /// 交易特性
- ///
- public class TransactionAttribute : IInteropInterface, ISerializable
- {
- ///
- /// 用途
- ///
- public TransactionAttributeUsage Usage;
- ///
- /// 特定于用途的外部数据
- ///
- public byte[] Data;
-
- public int Size
- {
- get
- {
- if (Usage == TransactionAttributeUsage.ContractHash || Usage == TransactionAttributeUsage.ECDH02 || Usage == TransactionAttributeUsage.ECDH03 || Usage == TransactionAttributeUsage.Vote || (Usage >= TransactionAttributeUsage.Hash1 && Usage <= TransactionAttributeUsage.Hash15))
- return sizeof(TransactionAttributeUsage) + 32;
- else if (Usage == TransactionAttributeUsage.Script)
- return sizeof(TransactionAttributeUsage) + 20;
- else if (Usage == TransactionAttributeUsage.DescriptionUrl)
- return sizeof(TransactionAttributeUsage) + sizeof(byte) + Data.Length;
- else
- return sizeof(TransactionAttributeUsage) + Data.GetVarSize();
- }
- }
-
- void ISerializable.Deserialize(BinaryReader reader)
- {
- Usage = (TransactionAttributeUsage)reader.ReadByte();
- if (Usage == TransactionAttributeUsage.ContractHash || Usage == TransactionAttributeUsage.Vote || (Usage >= TransactionAttributeUsage.Hash1 && Usage <= TransactionAttributeUsage.Hash15))
- Data = reader.ReadBytes(32);
- else if (Usage == TransactionAttributeUsage.ECDH02 || Usage == TransactionAttributeUsage.ECDH03)
- Data = new[] { (byte)Usage }.Concat(reader.ReadBytes(32)).ToArray();
- else if (Usage == TransactionAttributeUsage.Script)
- Data = reader.ReadBytes(20);
- else if (Usage == TransactionAttributeUsage.DescriptionUrl)
- Data = reader.ReadBytes(reader.ReadByte());
- else if (Usage == TransactionAttributeUsage.Description || Usage >= TransactionAttributeUsage.Remark)
- Data = reader.ReadVarBytes(ushort.MaxValue);
- else
- throw new FormatException();
- }
-
- void ISerializable.Serialize(BinaryWriter writer)
- {
- writer.Write((byte)Usage);
- if (Usage == TransactionAttributeUsage.DescriptionUrl)
- writer.Write((byte)Data.Length);
- else if (Usage == TransactionAttributeUsage.Description || Usage >= TransactionAttributeUsage.Remark)
- writer.WriteVarInt(Data.Length);
- if (Usage == TransactionAttributeUsage.ECDH02 || Usage == TransactionAttributeUsage.ECDH03)
- writer.Write(Data, 1, 32);
- else
- writer.Write(Data);
- }
-
- ///
- /// 变成json对象
- ///
- /// 返回json对象
- public JObject ToJson()
- {
- JObject json = new JObject();
- json["usage"] = Usage;
- json["data"] = Data.ToHexString();
- return json;
- }
- }
-}
diff --git a/neo/Core/TransactionAttributeUsage.cs b/neo/Core/TransactionAttributeUsage.cs
deleted file mode 100644
index 74079f295d..0000000000
--- a/neo/Core/TransactionAttributeUsage.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-namespace Neo.Core
-{
- ///
- /// 表示交易特性的用途
- ///
- public enum TransactionAttributeUsage : byte
- {
- ///
- /// 外部合同的散列值
- ///
- ContractHash = 0x00,
-
- ///
- /// 用于ECDH密钥交换的公钥,该公钥的第一个字节为0x02
- ///
- ECDH02 = 0x02,
- ///
- /// 用于ECDH密钥交换的公钥,该公钥的第一个字节为0x03
- ///
- ECDH03 = 0x03,
-
- ///
- /// 用于对交易进行额外的验证
- ///
- Script = 0x20,
-
- Vote = 0x30,
-
- DescriptionUrl = 0x81,
- Description = 0x90,
-
- Hash1 = 0xa1,
- Hash2 = 0xa2,
- Hash3 = 0xa3,
- Hash4 = 0xa4,
- Hash5 = 0xa5,
- Hash6 = 0xa6,
- Hash7 = 0xa7,
- Hash8 = 0xa8,
- Hash9 = 0xa9,
- Hash10 = 0xaa,
- Hash11 = 0xab,
- Hash12 = 0xac,
- Hash13 = 0xad,
- Hash14 = 0xae,
- Hash15 = 0xaf,
-
- ///
- /// 备注
- ///
- Remark = 0xf0,
- Remark1 = 0xf1,
- Remark2 = 0xf2,
- Remark3 = 0xf3,
- Remark4 = 0xf4,
- Remark5 = 0xf5,
- Remark6 = 0xf6,
- Remark7 = 0xf7,
- Remark8 = 0xf8,
- Remark9 = 0xf9,
- Remark10 = 0xfa,
- Remark11 = 0xfb,
- Remark12 = 0xfc,
- Remark13 = 0xfd,
- Remark14 = 0xfe,
- Remark15 = 0xff
- }
-}
diff --git a/neo/Core/TransactionOutput.cs b/neo/Core/TransactionOutput.cs
deleted file mode 100644
index ad69315fd9..0000000000
--- a/neo/Core/TransactionOutput.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using Neo.IO;
-using Neo.IO.Json;
-using Neo.VM;
-using Neo.Wallets;
-using System;
-using System.IO;
-
-namespace Neo.Core
-{
- ///
- /// 交易输出
- ///
- public class TransactionOutput : IInteropInterface, ISerializable
- {
- ///
- /// 资产编号
- ///
- public UInt256 AssetId;
- ///
- /// 金额
- ///
- public Fixed8 Value;
- ///
- /// 收款地址
- ///
- public UInt160 ScriptHash;
-
- public int Size => AssetId.Size + Value.Size + ScriptHash.Size;
-
- void ISerializable.Deserialize(BinaryReader reader)
- {
- this.AssetId = reader.ReadSerializable();
- this.Value = reader.ReadSerializable();
- if (Value <= Fixed8.Zero) throw new FormatException();
- this.ScriptHash = reader.ReadSerializable();
- }
-
- void ISerializable.Serialize(BinaryWriter writer)
- {
- writer.Write(AssetId);
- writer.Write(Value);
- writer.Write(ScriptHash);
- }
-
- ///
- /// 将交易输出转变为json对象
- ///
- /// 该交易输出在交易中的索引
- /// 返回json对象
- public JObject ToJson(ushort index)
- {
- JObject json = new JObject();
- json["n"] = index;
- json["asset"] = AssetId.ToString();
- json["value"] = Value.ToString();
- json["address"] = Wallet.ToAddress(ScriptHash);
- return json;
- }
- }
-}
diff --git a/neo/Core/TransactionResult.cs b/neo/Core/TransactionResult.cs
deleted file mode 100644
index 92448610fa..0000000000
--- a/neo/Core/TransactionResult.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Neo.Core
-{
- ///
- /// 交易结果,表示交易中资产的变化量
- ///
- public class TransactionResult
- {
- ///
- /// 资产编号
- ///
- public UInt256 AssetId;
- ///
- /// 该资产的变化量
- ///
- public Fixed8 Amount;
- }
-}
diff --git a/neo/Core/TransactionType.cs b/neo/Core/TransactionType.cs
deleted file mode 100644
index ea60017ef8..0000000000
--- a/neo/Core/TransactionType.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma warning disable CS0612
-
-using Neo.IO.Caching;
-
-namespace Neo.Core
-{
- ///
- /// 交易类型
- ///
- public enum TransactionType : byte
- {
- ///
- /// 用于分配字节费的特殊交易
- ///
- [ReflectionCache(typeof(MinerTransaction))]
- MinerTransaction = 0x00,
- ///
- /// 用于分发资产的特殊交易
- ///
- [ReflectionCache(typeof(IssueTransaction))]
- IssueTransaction = 0x01,
- [ReflectionCache(typeof(ClaimTransaction))]
- ClaimTransaction = 0x02,
- ///
- /// 用于报名成为记账候选人的特殊交易
- ///
- [ReflectionCache(typeof(EnrollmentTransaction))]
- EnrollmentTransaction = 0x20,
- ///
- /// 用于资产登记的特殊交易
- ///
- [ReflectionCache(typeof(RegisterTransaction))]
- RegisterTransaction = 0x40,
- ///
- /// 合约交易,这是最常用的一种交易
- ///
- [ReflectionCache(typeof(ContractTransaction))]
- ContractTransaction = 0x80,
- [ReflectionCache(typeof(StateTransaction))]
- StateTransaction = 0x90,
- ///
- /// Publish scripts to the blockchain for being invoked later.
- ///
- [ReflectionCache(typeof(PublishTransaction))]
- PublishTransaction = 0xd0,
- [ReflectionCache(typeof(InvocationTransaction))]
- InvocationTransaction = 0xd1
- }
-}
diff --git a/neo/Core/UnspentCoinState.cs b/neo/Core/UnspentCoinState.cs
deleted file mode 100644
index 76caa7d447..0000000000
--- a/neo/Core/UnspentCoinState.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using Neo.IO;
-using System.IO;
-using System.Linq;
-
-namespace Neo.Core
-{
- public class UnspentCoinState : StateBase, ICloneable
- {
- public CoinState[] Items;
-
- public override int Size => base.Size + Items.GetVarSize();
-
- UnspentCoinState ICloneable.Clone()
- {
- return new UnspentCoinState
- {
- Items = (CoinState[])Items.Clone()
- };
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- Items = reader.ReadVarBytes().Select(p => (CoinState)p).ToArray();
- }
-
- void ICloneable.FromReplica(UnspentCoinState replica)
- {
- Items = replica.Items;
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.WriteVarBytes(Items.Cast().ToArray());
- }
- }
-}
diff --git a/neo/Core/ValidatorState.cs b/neo/Core/ValidatorState.cs
deleted file mode 100644
index 1292cbbcdb..0000000000
--- a/neo/Core/ValidatorState.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using Neo.Cryptography.ECC;
-using Neo.IO;
-using System.IO;
-
-namespace Neo.Core
-{
- public class ValidatorState : StateBase, ICloneable
- {
- public ECPoint PublicKey;
- public bool Registered;
- public Fixed8 Votes;
-
- public override int Size => base.Size + PublicKey.Size + sizeof(bool) + Votes.Size;
-
- public ValidatorState() { }
-
- public ValidatorState(ECPoint pubkey)
- {
- this.PublicKey = pubkey;
- this.Registered = false;
- this.Votes = Fixed8.Zero;
- }
-
- ValidatorState ICloneable.Clone()
- {
- return new ValidatorState
- {
- PublicKey = PublicKey,
- Registered = Registered,
- Votes = Votes
- };
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- PublicKey = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1);
- Registered = reader.ReadBoolean();
- Votes = reader.ReadSerializable();
- }
-
- void ICloneable.FromReplica(ValidatorState replica)
- {
- PublicKey = replica.PublicKey;
- Registered = replica.Registered;
- Votes = replica.Votes;
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(PublicKey);
- writer.Write(Registered);
- writer.Write(Votes);
- }
- }
-}
diff --git a/neo/Core/ValidatorsCountState.cs b/neo/Core/ValidatorsCountState.cs
deleted file mode 100644
index 9ad96c330a..0000000000
--- a/neo/Core/ValidatorsCountState.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using Neo.IO;
-using System.IO;
-
-namespace Neo.Core
-{
- public class ValidatorsCountState : StateBase, ICloneable
- {
- public Fixed8[] Votes;
-
- public override int Size => base.Size + Votes.GetVarSize();
-
- public ValidatorsCountState()
- {
- this.Votes = new Fixed8[Blockchain.MaxValidators];
- }
-
- ValidatorsCountState ICloneable.Clone()
- {
- return new ValidatorsCountState
- {
- Votes = (Fixed8[])Votes.Clone()
- };
- }
-
- public override void Deserialize(BinaryReader reader)
- {
- base.Deserialize(reader);
- Votes = reader.ReadSerializableArray();
- }
-
- void ICloneable.FromReplica(ValidatorsCountState replica)
- {
- Votes = replica.Votes;
- }
-
- public override void Serialize(BinaryWriter writer)
- {
- base.Serialize(writer);
- writer.Write(Votes);
- }
- }
-}
diff --git a/neo/Core/Witness.cs b/neo/Core/Witness.cs
deleted file mode 100644
index b906fe6257..0000000000
--- a/neo/Core/Witness.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Neo.IO;
-using Neo.IO.Json;
-using System.IO;
-
-namespace Neo.Core
-{
- public class Witness : ISerializable
- {
- public byte[] InvocationScript;
- public byte[] VerificationScript;
-
- private UInt160 _scriptHash;
- public virtual UInt160 ScriptHash
- {
- get
- {
- if (_scriptHash == null)
- {
- _scriptHash = VerificationScript.ToScriptHash();
- }
- return _scriptHash;
- }
- }
-
- public int Size => InvocationScript.GetVarSize() + VerificationScript.GetVarSize();
-
- void ISerializable.Deserialize(BinaryReader reader)
- {
- InvocationScript = reader.ReadVarBytes(65536);
- VerificationScript = reader.ReadVarBytes(65536);
- }
-
- void ISerializable.Serialize(BinaryWriter writer)
- {
- writer.WriteVarBytes(InvocationScript);
- writer.WriteVarBytes(VerificationScript);
- }
-
- ///
- /// 变成json对象
- ///
- /// 返回json对象
- public JObject ToJson()
- {
- JObject json = new JObject();
- json["invocation"] = InvocationScript.ToHexString();
- json["verification"] = VerificationScript.ToHexString();
- return json;
- }
- }
-}
diff --git a/neo/Cryptography/Base58.cs b/neo/Cryptography/Base58.cs
deleted file mode 100644
index 1d8107c1ff..0000000000
--- a/neo/Cryptography/Base58.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-using System;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-
-namespace Neo.Cryptography
-{
- public static class Base58
- {
- ///
- /// base58编码的字母表
- ///
- public const string Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
-
- ///
- /// 解码
- ///
- /// 要解码的字符串
- /// 返回解码后的字节数组
- public static byte[] Decode(string input)
- {
- BigInteger bi = BigInteger.Zero;
- for (int i = input.Length - 1; i >= 0; i--)
- {
- int index = Alphabet.IndexOf(input[i]);
- if (index == -1)
- throw new FormatException();
- bi += index * BigInteger.Pow(58, input.Length - 1 - i);
- }
- byte[] bytes = bi.ToByteArray();
- Array.Reverse(bytes);
- bool stripSignByte = bytes.Length > 1 && bytes[0] == 0 && bytes[1] >= 0x80;
- int leadingZeros = 0;
- for (int i = 0; i < input.Length && input[i] == Alphabet[0]; i++)
- {
- leadingZeros++;
- }
- byte[] tmp = new byte[bytes.Length - (stripSignByte ? 1 : 0) + leadingZeros];
- Array.Copy(bytes, stripSignByte ? 1 : 0, tmp, leadingZeros, tmp.Length - leadingZeros);
- return tmp;
- }
-
- ///
- /// 编码
- ///
- /// 要编码的字节数组
- /// 返回编码后的字符串
- public static string Encode(byte[] input)
- {
- BigInteger value = new BigInteger(new byte[1].Concat(input).Reverse().ToArray());
- StringBuilder sb = new StringBuilder();
- while (value >= 58)
- {
- BigInteger mod = value % 58;
- sb.Insert(0, Alphabet[(int)mod]);
- value /= 58;
- }
- sb.Insert(0, Alphabet[(int)value]);
- foreach (byte b in input)
- {
- if (b == 0)
- sb.Insert(0, Alphabet[0]);
- else
- break;
- }
- return sb.ToString();
- }
- }
-}
diff --git a/neo/Cryptography/BloomFilter.cs b/neo/Cryptography/BloomFilter.cs
deleted file mode 100644
index 637cd9fac5..0000000000
--- a/neo/Cryptography/BloomFilter.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System.Collections;
-using System.Linq;
-
-namespace Neo.Cryptography
-{
- public class BloomFilter
- {
- private readonly uint[] seeds;
- private readonly BitArray bits;
-
- public int K => seeds.Length;
-
- public int M => bits.Length;
-
- public uint Tweak { get; private set; }
-
- public BloomFilter(int m, int k, uint nTweak, byte[] elements = null)
- {
- this.seeds = Enumerable.Range(0, k).Select(p => (uint)p * 0xFBA4C795 + nTweak).ToArray();
- this.bits = elements == null ? new BitArray(m) : new BitArray(elements);
- this.bits.Length = m;
- this.Tweak = nTweak;
- }
-
- public void Add(byte[] element)
- {
- foreach (uint i in seeds.AsParallel().Select(s => element.Murmur32(s)))
- bits.Set((int)(i % (uint)bits.Length), true);
- }
-
- public bool Check(byte[] element)
- {
- foreach (uint i in seeds.AsParallel().Select(s => element.Murmur32(s)))
- if (!bits.Get((int)(i % (uint)bits.Length)))
- return false;
- return true;
- }
-
- public void GetBits(byte[] newBits)
- {
- bits.CopyTo(newBits, 0);
- }
- }
-}
diff --git a/neo/Cryptography/Crypto.cs b/neo/Cryptography/Crypto.cs
deleted file mode 100644
index 38a5eaeb8b..0000000000
--- a/neo/Cryptography/Crypto.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using Neo.VM;
-using System;
-using System.Linq;
-using System.Security.Cryptography;
-
-namespace Neo.Cryptography
-{
- public class Crypto : ICrypto
- {
- public static readonly Crypto Default = new Crypto();
-
- public byte[] Hash160(byte[] message)
- {
- return message.Sha256().RIPEMD160();
- }
-
- public byte[] Hash256(byte[] message)
- {
- return message.Sha256().Sha256();
- }
-
- public byte[] Sign(byte[] message, byte[] prikey, byte[] pubkey)
- {
- using (var ecdsa = ECDsa.Create(new ECParameters
- {
- Curve = ECCurve.NamedCurves.nistP256,
- D = prikey,
- Q = new ECPoint
- {
- X = pubkey.Take(32).ToArray(),
- Y = pubkey.Skip(32).ToArray()
- }
- }))
- {
- return ecdsa.SignData(message, HashAlgorithmName.SHA256);
- }
- }
-
- public bool VerifySignature(byte[] message, byte[] signature, byte[] pubkey)
- {
- if (pubkey.Length == 33 && (pubkey[0] == 0x02 || pubkey[0] == 0x03))
- {
- try
- {
- pubkey = Cryptography.ECC.ECPoint.DecodePoint(pubkey, Cryptography.ECC.ECCurve.Secp256r1).EncodePoint(false).Skip(1).ToArray();
- }
- catch
- {
- return false;
- }
- }
- else if (pubkey.Length == 65 && pubkey[0] == 0x04)
- {
- pubkey = pubkey.Skip(1).ToArray();
- }
- else if (pubkey.Length != 64)
- {
- throw new ArgumentException();
- }
- using (var ecdsa = ECDsa.Create(new ECParameters
- {
- Curve = ECCurve.NamedCurves.nistP256,
- Q = new ECPoint
- {
- X = pubkey.Take(32).ToArray(),
- Y = pubkey.Skip(32).ToArray()
- }
- }))
- {
- return ecdsa.VerifyData(message, signature, HashAlgorithmName.SHA256);
- }
- }
- }
-}
diff --git a/neo/Cryptography/ECC/ECCurve.cs b/neo/Cryptography/ECC/ECCurve.cs
deleted file mode 100644
index aa4a956f76..0000000000
--- a/neo/Cryptography/ECC/ECCurve.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System.Globalization;
-using System.Numerics;
-
-namespace Neo.Cryptography.ECC
-{
- ///
- /// ECC椭圆曲线参数
- ///
- public class ECCurve
- {
- internal readonly BigInteger Q;
- internal readonly ECFieldElement A;
- internal readonly ECFieldElement B;
- internal readonly BigInteger N;
- ///
- /// 无穷远点
- ///
- public readonly ECPoint Infinity;
- ///
- /// 基点
- ///
- public readonly ECPoint G;
-
- private ECCurve(BigInteger Q, BigInteger A, BigInteger B, BigInteger N, byte[] G)
- {
- this.Q = Q;
- this.A = new ECFieldElement(A, this);
- this.B = new ECFieldElement(B, this);
- this.N = N;
- this.Infinity = new ECPoint(null, null, this);
- this.G = ECPoint.DecodePoint(G, this);
- }
-
- ///
- /// 曲线secp256k1
- ///
- public static readonly ECCurve Secp256k1 = new ECCurve
- (
- BigInteger.Parse("00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", NumberStyles.AllowHexSpecifier),
- BigInteger.Zero,
- 7,
- BigInteger.Parse("00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", NumberStyles.AllowHexSpecifier),
- ("04" + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8").HexToBytes()
- );
-
- ///
- /// 曲线secp256r1
- ///
- public static readonly ECCurve Secp256r1 = new ECCurve
- (
- BigInteger.Parse("00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", NumberStyles.AllowHexSpecifier),
- BigInteger.Parse("00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", NumberStyles.AllowHexSpecifier),
- BigInteger.Parse("005AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", NumberStyles.AllowHexSpecifier),
- BigInteger.Parse("00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", NumberStyles.AllowHexSpecifier),
- ("04" + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5").HexToBytes()
- );
- }
-}
diff --git a/neo/Cryptography/ECC/ECDsa.cs b/neo/Cryptography/ECC/ECDsa.cs
deleted file mode 100644
index 8e0f028e99..0000000000
--- a/neo/Cryptography/ECC/ECDsa.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using System;
-using System.Linq;
-using System.Numerics;
-using System.Security.Cryptography;
-
-namespace Neo.Cryptography.ECC
-{
- ///
- /// 提供椭圆曲线数字签名算法(ECDSA)的功能
- ///
- public class ECDsa
- {
- private readonly byte[] privateKey;
- private readonly ECPoint publicKey;
- private readonly ECCurve curve;
-
- ///
- /// 根据指定的私钥和曲线参数来创建新的ECDsa对象,该对象可用于签名
- ///
- /// 私钥
- /// 椭圆曲线参数
- public ECDsa(byte[] privateKey, ECCurve curve)
- : this(curve.G * privateKey)
- {
- this.privateKey = privateKey;
- }
-
- ///
- /// 根据指定的公钥来创建新的ECDsa对象,该对象可用于验证签名
- ///
- /// 公钥
- public ECDsa(ECPoint publicKey)
- {
- this.publicKey = publicKey;
- this.curve = publicKey.Curve;
- }
-
- private BigInteger CalculateE(BigInteger n, byte[] message)
- {
- int messageBitLength = message.Length * 8;
- BigInteger trunc = new BigInteger(message.Reverse().Concat(new byte[1]).ToArray());
- if (n.GetBitLength() < messageBitLength)
- {
- trunc >>= messageBitLength - n.GetBitLength();
- }
- return trunc;
- }
-
- ///
- /// 生成椭圆曲线数字签名
- ///
- /// 要签名的消息
- /// 返回签名的数字编码(r,s)
- public BigInteger[] GenerateSignature(byte[] message)
- {
- if (privateKey == null) throw new InvalidOperationException();
- BigInteger e = CalculateE(curve.N, message);
- BigInteger d = new BigInteger(privateKey.Reverse().Concat(new byte[1]).ToArray());
- BigInteger r, s;
- using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
- {
- do
- {
- BigInteger k;
- do
- {
- do
- {
- k = rng.NextBigInteger(curve.N.GetBitLength());
- }
- while (k.Sign == 0 || k.CompareTo(curve.N) >= 0);
- ECPoint p = ECPoint.Multiply(curve.G, k);
- BigInteger x = p.X.Value;
- r = x.Mod(curve.N);
- }
- while (r.Sign == 0);
- s = (k.ModInverse(curve.N) * (e + d * r)).Mod(curve.N);
- if (s > curve.N / 2)
- {
- s = curve.N - s;
- }
- }
- while (s.Sign == 0);
- }
- return new BigInteger[] { r, s };
- }
-
- private static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger k, ECPoint Q, BigInteger l)
- {
- int m = Math.Max(k.GetBitLength(), l.GetBitLength());
- ECPoint Z = P + Q;
- ECPoint R = P.Curve.Infinity;
- for (int i = m - 1; i >= 0; --i)
- {
- R = R.Twice();
- if (k.TestBit(i))
- {
- if (l.TestBit(i))
- R = R + Z;
- else
- R = R + P;
- }
- else
- {
- if (l.TestBit(i))
- R = R + Q;
- }
- }
- return R;
- }
-
- ///
- /// 验证签名的合法性
- ///
- /// 要验证的消息
- /// 签名的数字编码
- /// 签名的数字编码
- /// 返回验证的结果
- public bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
- {
- if (r.Sign < 1 || s.Sign < 1 || r.CompareTo(curve.N) >= 0 || s.CompareTo(curve.N) >= 0)
- return false;
- BigInteger e = CalculateE(curve.N, message);
- BigInteger c = s.ModInverse(curve.N);
- BigInteger u1 = (e * c).Mod(curve.N);
- BigInteger u2 = (r * c).Mod(curve.N);
- ECPoint point = SumOfTwoMultiplies(curve.G, u1, publicKey, u2);
- BigInteger v = point.X.Value.Mod(curve.N);
- return v.Equals(r);
- }
- }
-}
diff --git a/neo/Cryptography/ECC/ECFieldElement.cs b/neo/Cryptography/ECC/ECFieldElement.cs
deleted file mode 100644
index 4ce303dcc8..0000000000
--- a/neo/Cryptography/ECC/ECFieldElement.cs
+++ /dev/null
@@ -1,182 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Linq;
-using System.Numerics;
-
-namespace Neo.Cryptography.ECC
-{
- internal class ECFieldElement : IComparable, IEquatable
- {
- internal readonly BigInteger Value;
- private readonly ECCurve curve;
-
- public ECFieldElement(BigInteger value, ECCurve curve)
- {
- if (value >= curve.Q)
- throw new ArgumentException("x value too large in field element");
- this.Value = value;
- this.curve = curve;
- }
-
- public int CompareTo(ECFieldElement other)
- {
- if (ReferenceEquals(this, other)) return 0;
- return Value.CompareTo(other.Value);
- }
-
- public override bool Equals(object obj)
- {
- if (obj == this)
- return true;
-
- ECFieldElement other = obj as ECFieldElement;
-
- if (other == null)
- return false;
-
- return Equals(other);
- }
-
- public bool Equals(ECFieldElement other)
- {
- return Value.Equals(other.Value);
- }
-
- private static BigInteger[] FastLucasSequence(BigInteger p, BigInteger P, BigInteger Q, BigInteger k)
- {
- int n = k.GetBitLength();
- int s = k.GetLowestSetBit();
-
- Debug.Assert(k.TestBit(s));
-
- BigInteger Uh = 1;
- BigInteger Vl = 2;
- BigInteger Vh = P;
- BigInteger Ql = 1;
- BigInteger Qh = 1;
-
- for (int j = n - 1; j >= s + 1; --j)
- {
- Ql = (Ql * Qh).Mod(p);
-
- if (k.TestBit(j))
- {
- Qh = (Ql * Q).Mod(p);
- Uh = (Uh * Vh).Mod(p);
- Vl = (Vh * Vl - P * Ql).Mod(p);
- Vh = ((Vh * Vh) - (Qh << 1)).Mod(p);
- }
- else
- {
- Qh = Ql;
- Uh = (Uh * Vl - Ql).Mod(p);
- Vh = (Vh * Vl - P * Ql).Mod(p);
- Vl = ((Vl * Vl) - (Ql << 1)).Mod(p);
- }
- }
-
- Ql = (Ql * Qh).Mod(p);
- Qh = (Ql * Q).Mod(p);
- Uh = (Uh * Vl - Ql).Mod(p);
- Vl = (Vh * Vl - P * Ql).Mod(p);
- Ql = (Ql * Qh).Mod(p);
-
- for (int j = 1; j <= s; ++j)
- {
- Uh = Uh * Vl * p;
- Vl = ((Vl * Vl) - (Ql << 1)).Mod(p);
- Ql = (Ql * Ql).Mod(p);
- }
-
- return new BigInteger[] { Uh, Vl };
- }
-
- public override int GetHashCode()
- {
- return Value.GetHashCode();
- }
-
- public ECFieldElement Sqrt()
- {
- if (curve.Q.TestBit(1))
- {
- ECFieldElement z = new ECFieldElement(BigInteger.ModPow(Value, (curve.Q >> 2) + 1, curve.Q), curve);
- return z.Square().Equals(this) ? z : null;
- }
- BigInteger qMinusOne = curve.Q - 1;
- BigInteger legendreExponent = qMinusOne >> 1;
- if (BigInteger.ModPow(Value, legendreExponent, curve.Q) != 1)
- return null;
- BigInteger u = qMinusOne >> 2;
- BigInteger k = (u << 1) + 1;
- BigInteger Q = this.Value;
- BigInteger fourQ = (Q << 2).Mod(curve.Q);
- BigInteger U, V;
- do
- {
- Random rand = new Random();
- BigInteger P;
- do
- {
- P = rand.NextBigInteger(curve.Q.GetBitLength());
- }
- while (P >= curve.Q || BigInteger.ModPow(P * P - fourQ, legendreExponent, curve.Q) != qMinusOne);
- BigInteger[] result = FastLucasSequence(curve.Q, P, Q, k);
- U = result[0];
- V = result[1];
- if ((V * V).Mod(curve.Q) == fourQ)
- {
- if (V.TestBit(0))
- {
- V += curve.Q;
- }
- V >>= 1;
- Debug.Assert((V * V).Mod(curve.Q) == Value);
- return new ECFieldElement(V, curve);
- }
- }
- while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));
- return null;
- }
-
- public ECFieldElement Square()
- {
- return new ECFieldElement((Value * Value).Mod(curve.Q), curve);
- }
-
- public byte[] ToByteArray()
- {
- byte[] data = Value.ToByteArray();
- if (data.Length == 32)
- return data.Reverse().ToArray();
- if (data.Length > 32)
- return data.Take(32).Reverse().ToArray();
- return Enumerable.Repeat(0, 32 - data.Length).Concat(data.Reverse()).ToArray();
- }
-
- public static ECFieldElement operator -(ECFieldElement x)
- {
- return new ECFieldElement((-x.Value).Mod(x.curve.Q), x.curve);
- }
-
- public static ECFieldElement operator *(ECFieldElement x, ECFieldElement y)
- {
- return new ECFieldElement((x.Value * y.Value).Mod(x.curve.Q), x.curve);
- }
-
- public static ECFieldElement operator /(ECFieldElement x, ECFieldElement y)
- {
- return new ECFieldElement((x.Value * y.Value.ModInverse(x.curve.Q)).Mod(x.curve.Q), x.curve);
- }
-
- public static ECFieldElement operator +(ECFieldElement x, ECFieldElement y)
- {
- return new ECFieldElement((x.Value + y.Value).Mod(x.curve.Q), x.curve);
- }
-
- public static ECFieldElement operator -(ECFieldElement x, ECFieldElement y)
- {
- return new ECFieldElement((x.Value - y.Value).Mod(x.curve.Q), x.curve);
- }
- }
-}
diff --git a/neo/Cryptography/ECC/ECPoint.cs b/neo/Cryptography/ECC/ECPoint.cs
deleted file mode 100644
index ba529f8b02..0000000000
--- a/neo/Cryptography/ECC/ECPoint.cs
+++ /dev/null
@@ -1,464 +0,0 @@
-using Neo.IO;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Numerics;
-
-namespace Neo.Cryptography.ECC
-{
- public class ECPoint : IComparable