-
Notifications
You must be signed in to change notification settings - Fork 106
add documents #1307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
Jim8y
wants to merge
1
commit into
master
Choose a base branch
from
documents
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+5,354
−0
Draft
add documents #1307
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# Using the Compiler (`nccs`) | ||
|
||
The Neo C# Compiler, often invoked as `nccs` (Neo Compiler C Sharp), is the command-line tool responsible for transforming your C# smart contract project into executable Neo Virtual Machine (NeoVM) bytecode and associated metadata files. | ||
|
||
## Installation | ||
|
||
The compiler is typically used as part of the `neo-devpack-dotnet` package or SDK installation. Ensure you have the .NET SDK installed. Depending on your setup, you might invoke the compiler via: | ||
|
||
1. **Direct DLL Execution:** `dotnet <path_to_nccs_dll>/nccs.dll <arguments...>` | ||
2. **.NET Tool (if installed):** `nccs <arguments...>` | ||
3. **Within Visual Studio/IDE:** Build process might automatically invoke the compiler. | ||
|
||
Refer to the [Getting Started](./../02-getting-started/02-installation.md) section for detailed installation instructions. | ||
|
||
## Command-Line Interface (CLI) | ||
|
||
The basic syntax for the compiler is: | ||
|
||
```bash | ||
nccs [paths...] [options...] | ||
``` | ||
|
||
### Input Paths (`paths...`) | ||
|
||
You need to provide the compiler with the C# source code to compile. This can be done in several ways: | ||
|
||
* **Project File (`.csproj`):** | ||
```bash | ||
nccs MyContractProject.csproj [options...] | ||
``` | ||
This is the recommended approach as it uses the project file to determine source files, dependencies, and some compilation settings. | ||
|
||
* **Directory:** | ||
```bash | ||
nccs ./path/to/contract/directory/ [options...] | ||
``` | ||
The compiler will search for a `.csproj` file in the specified directory. If found, it processes it. If not, it searches for `.cs` files recursively (excluding `obj` folders) and compiles them. | ||
|
||
* **Specific Source Files (`.cs`):** | ||
```bash | ||
nccs Contract1.cs Helper.cs [options...] | ||
``` | ||
You can specify one or more C# source files directly. The output base name will typically be derived from the first `.cs` file unless overridden with `--base-name`. | ||
|
||
* **No Path Specified:** | ||
```bash | ||
nccs [options...] | ||
``` | ||
If no path is provided, the compiler attempts to process the current working directory, looking for `.csproj` or `.cs` files as described above. | ||
|
||
* **NEF File for Optimization (`.nef`):** | ||
```bash | ||
nccs MyContract.nef --optimize=Experimental [other_options...] | ||
``` | ||
The compiler can also take a compiled `.nef` file as input *specifically for optimization* using the `--optimize=Experimental` flag. It requires the corresponding `.manifest.json` and optionally the `.nefdbgnfo` file to be present in the same directory. | ||
|
||
### Compiler Outputs | ||
|
||
Upon successful compilation, `nccs` generates several files, typically in the output directory (default: `bin/sc/` relative to the project/source location): | ||
|
||
1. **`.nef` (Neo Executable Format):** | ||
* **File:** `<BaseName>.nef` (e.g., `MyContract.nef`) | ||
* **Content:** The compiled NeoVM bytecode that can be deployed to the Neo blockchain. | ||
|
||
2. **`.manifest.json` (Contract Manifest):** | ||
* **File:** `<BaseName>.manifest.json` (e.g., `MyContract.manifest.json`) | ||
* **Content:** JSON metadata describing the contract's ABI (methods, parameters, return types, events), permissions, supported standards, and other essential information needed for interaction and deployment. | ||
|
||
3. **`.nefdbgnfo` / `.debug.json` (Debug Information):** | ||
* **File:** `<BaseName>.nefdbgnfo` (e.g., `MyContract.nefdbgnfo`) | ||
* **Content:** A zip archive containing a `<BaseName>.debug.json` file. This JSON file maps NeoVM instructions back to the original C# source code lines and includes information about variables and method entry/exit points. This is crucial for debugging smart contracts using tools like Neo Debugger. Generated when the `--debug` option is enabled. | ||
|
||
### Optional Outputs | ||
|
||
Depending on the compiler options used, additional files might be generated: | ||
|
||
* **`.asm` (Assembly Listing):** | ||
* **File:** `<BaseName>.asm` (e.g., `MyContract.asm`) | ||
* **Content:** Human-readable representation of the generated NeoVM instructions (opcodes). Generated with the `--assembly` option. | ||
|
||
* **`.nef.txt` (DumpNef Output):** | ||
* **File:** `<BaseName>.nef.txt` (e.g., `MyContract.nef.txt`) | ||
* **Content:** Detailed breakdown of the NEF file structure, including script hash, opcodes with offsets, and potentially integrated debug information. Generated with the `--assembly` option. | ||
|
||
* **Artifacts (`.cs`, `.dll`):** | ||
* **Files:** `<BaseName>.artifacts.cs`, `<BaseName>.artifacts.dll` | ||
* **Content:** C# source code (`.cs`) or a compiled library (`.dll`) generated from the contract's manifest. These artifacts can simplify contract interaction in off-chain C# applications or testing environments. Generated with the `--generate-artifacts` option. | ||
|
||
### Example Usage | ||
|
||
* **Compile a project file with debug info:** | ||
```bash | ||
nccs MyProject.csproj --debug | ||
``` | ||
|
||
* **Compile specific C# files into a specific output directory:** | ||
```bash | ||
nccs Contract.cs Storage.cs --output ./build --base-name MyAwesomeContract | ||
``` | ||
|
||
* **Compile a project and generate assembly listing:** | ||
```bash | ||
nccs . --assembly | ||
``` | ||
|
||
## Integration | ||
|
||
While `nccs` is a powerful command-line tool, it's often integrated into development workflows: | ||
|
||
* **Visual Studio / Rider:** Building a Neo Smart Contract project within these IDEs typically triggers the `nccs` compiler automatically as part of the build process defined in the `.csproj` file. | ||
* **Build Scripts:** Custom build scripts can incorporate `nccs` commands for automated compilation and deployment pipelines. | ||
|
||
See the [Compiler Options](./02-compiler-options.md) page for a detailed list of available flags and settings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# Compiler Options | ||
|
||
The Neo C# Compiler (`nccs`) provides several command-line options to control the compilation process, output generation, and optimization levels. | ||
|
||
## Syntax | ||
|
||
```bash | ||
nccs [paths...] [options...] | ||
``` | ||
|
||
## Options | ||
|
||
Here is a list of the available options: | ||
|
||
* **`-o|--output <DIRECTORY>`** | ||
* **Purpose:** Specifies the directory where the output files (`.nef`, `.manifest.json`, etc.) will be generated. | ||
* **Default:** If not specified, defaults typically to `./bin/sc/` relative to the input project or source file location. | ||
* **Example:** `nccs MyContract.csproj --output ./build/` | ||
|
||
* **`--base-name <NAME>`** | ||
* **Purpose:** Sets the base name for the output files. For example, using `--base-name MyToken` will produce `MyToken.nef`, `MyToken.manifest.json`, etc. | ||
* **Default:** If not specified, the compiler usually infers the base name from the project file name or the first source file name. | ||
* **Example:** `nccs Contract.cs --base-name AwesomeContract` | ||
|
||
* **`-d|--debug [LEVEL]`** | ||
* **Purpose:** Enables the generation of debugging information (`.nefdbgnfo` file containing `.debug.json`). This is essential for debugging contracts. | ||
* **Levels:** | ||
* `None` (Default if option omitted): No debug info. | ||
* `Extended` (Default if option present without value, e.g., `--debug`): Includes sequence points, variable information, and method entry/exit points. | ||
* *(Other potential levels might exist depending on the compiler version, but `Extended` is the most common for debugging)*. | ||
* **Example (Extended Debug):** `nccs MyContract.csproj --debug` | ||
* **Example (Specific Level):** `nccs MyContract.csproj --debug Extended` | ||
|
||
* **`--nullable <STATE>`** | ||
* **Purpose:** Controls the handling of C# nullable reference types analysis during compilation. | ||
* **States:** | ||
* `Disable`: Nullable analysis is disabled. | ||
* `Enable`: Nullable analysis is enabled. | ||
* `Warnings`: Nullable analysis warnings are treated as warnings. | ||
* `Annotations` (Default): Respects nullable annotations (`?`) in the code. | ||
* `SafeOnly`: Enables stricter nullable analysis. | ||
* **Default:** `Annotations` | ||
* **Example:** `nccs MyContract.csproj --nullable Enable` | ||
|
||
* **`--checked`** | ||
* **Purpose:** Instructs the compiler to generate code that checks for arithmetic overflow and underflow exceptions at runtime. | ||
* **Default:** Disabled (unchecked). | ||
* **Example:** `nccs MyContract.csproj --checked` | ||
|
||
* **`--assembly`** | ||
* **Purpose:** Generates additional output files containing human-readable NeoVM assembly code (`.asm`) and a detailed NEF file dump (`.nef.txt`). Useful for low-level analysis and understanding the generated bytecode. | ||
* **Default:** Disabled. | ||
* **Example:** `nccs MyContract.csproj --assembly` | ||
|
||
* **`--generate-artifacts [KIND]`** | ||
* **Purpose:** Creates helper artifacts based on the contract manifest, simplifying off-chain interaction or testing. | ||
* **Kinds:** | ||
* `None` (Default): No artifacts generated. | ||
* `Source`: Generates a C# source file (`<BaseName>.artifacts.cs`). | ||
* `Library`: Generates a compiled C# library (`<BaseName>.artifacts.dll`). | ||
* `All`: Generates both `Source` and `Library`. | ||
* **Default:** `None` | ||
* **Example (Generate C# Source):** `nccs MyContract.csproj --generate-artifacts Source` | ||
* **Example (Generate Both):** `nccs MyContract.csproj --generate-artifacts All` | ||
|
||
* **`--security-analysis`** | ||
* **Purpose:** Performs a basic static security analysis on the compiled contract, checking for common pitfalls. | ||
* **Note:** This analysis may produce false positives and should be used as a supplementary check, not a replacement for thorough security auditing. | ||
* **Default:** Disabled. | ||
* **Example:** `nccs MyContract.csproj --security-analysis` | ||
|
||
* **`--optimize <LEVEL>`** | ||
* **Purpose:** Specifies the level of optimization to apply during compilation. | ||
* **Levels (Common):** | ||
* `None`: No optimizations. | ||
* `Basic`: Basic optimizations (peephole, etc.). | ||
* `All`: More comprehensive optimizations. | ||
* `Experimental`: Used specifically when providing a `.nef` file as input for optimization. | ||
* **Default:** Varies, often `Basic` or `All` depending on the compiler version/defaults. | ||
* **Example:** `nccs MyContract.csproj --optimize All` | ||
* **Example (Optimize existing NEF):** `nccs MyContract.nef --optimize=Experimental` | ||
|
||
* **`--no-inline`** | ||
* **Purpose:** Prevents the compiler from inlining method calls. Inlining can sometimes reduce call overhead but increase overall script size. | ||
* **Default:** Inlining is generally enabled. | ||
* **Example:** `nccs MyContract.csproj --no-inline` | ||
|
||
* **`--address-version <VERSION>`** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very good job, @Jim8y When was this included? I do not remember. |
||
* **Purpose:** Specifies the address version to be used by the compiler, particularly when generating addresses or interacting with address-related features. | ||
* **Default:** Uses the default address version from the Neo `ProtocolSettings` (typically 53 for N3). | ||
* **Example:** `nccs MyContract.csproj --address-version 53` | ||
|
||
* **`-?|-h|--help`** | ||
* **Purpose:** Displays the help message listing all available commands and options. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Debugging Information | ||
|
||
Effective debugging is crucial for developing reliable smart contracts. The Neo C# Compiler (`nccs`) facilitates debugging by generating detailed mapping information when the `--debug` option is enabled. | ||
|
||
## Enabling Debug Info Generation | ||
|
||
To generate debugging information, use the `-d` or `--debug` flag during compilation: | ||
|
||
```bash | ||
nccs MyContractProject.csproj --debug | ||
``` | ||
|
||
This command instructs the compiler to produce an additional output file. | ||
|
||
## The `.nefdbgnfo` File | ||
|
||
When debug generation is enabled, the compiler creates a file named `<BaseName>.nefdbgnfo` (e.g., `MyContract.nefdbgnfo`) in the output directory. | ||
|
||
This file is a standard Zip archive containing one primary file: | ||
|
||
* **`<BaseName>.debug.json`**: A JSON file holding the actual debug metadata. | ||
|
||
## The `.debug.json` File Format | ||
|
||
The `.debug.json` file contains the core information needed by debuggers to correlate the compiled NeoVM bytecode with the original C# source code. Its structure typically includes: | ||
|
||
* **`hash`**: The script hash of the compiled contract (`.nef` file). | ||
* **`entrypoint`**: The instruction pointer (offset) of the contract's entry point. | ||
* **`documents`**: An array of paths to the original C# source files involved in the compilation. | ||
* **`methods`**: An array describing the compiled methods: | ||
* **`id`**: A unique identifier for the method (e.g., `Namespace.ClassName,MethodName`). | ||
* **`name`**: The method's name and signature. | ||
* **`range`**: The start and end instruction offsets for the method's bytecode. | ||
* **`params`**: An array listing the method's parameters (name and type). | ||
* **`return`**: The method's return type. | ||
* **`variables`**: An array listing the local variables within the method (name, type, and scope range). | ||
* **`sequence-points`**: An array of critical mappings. Each point links a bytecode instruction offset to a specific location (document index, start line/column, end line/column) in the original C# source code. This is the core data used for stepping through code. | ||
* **`events`**: An array describing the events defined in the contract (similar structure to methods, listing parameters). | ||
* **`static-variables`**: An array listing static variables used in the contract. | ||
|
||
*(Note: The exact JSON structure might evolve slightly between compiler versions, but the core concepts remain the same.)* | ||
|
||
## Using Debug Information | ||
|
||
The `.nefdbgnfo` file (containing the `.debug.json`) is essential for debugging tools like: | ||
|
||
* **Neo Debugger (Visual Studio Code Extension):** This tool reads the `.nefdbgnfo` file alongside the `.nef` and source code to allow setting breakpoints, stepping through C# code, inspecting variables, and examining the contract's state during execution in a simulated environment (like `Neo Express` or a `TestEngine`). | ||
* **Other Debugging Environments:** Custom testing or debugging setups can parse the `.debug.json` to provide similar source-level debugging capabilities. | ||
|
||
Without the debug information generated by the `--debug` flag, debugging is limited to the NeoVM instruction level, which is significantly more complex and less intuitive than working directly with the C# source code. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Method Conversion to NeoVM Bytecode | ||
|
||
One of the core responsibilities of the Neo C# Compiler (`nccs`) is to translate the C# methods within your smart contract into executable Neo Virtual Machine (NeoVM) bytecode. This process involves analyzing the C# code and generating a corresponding sequence of NeoVM opcodes. | ||
|
||
## The Conversion Process | ||
|
||
The compiler leverages the .NET Compiler Platform (Roslyn) to parse and analyze your C# code. For each method identified as part of the smart contract, it performs the following steps: | ||
|
||
1. **Semantic Analysis:** Roslyn provides a detailed semantic model of the code, understanding types, method calls, variable scopes, and control flow. | ||
2. **Syntax Tree Traversal:** The compiler walks through the Abstract Syntax Tree (AST) of the method provided by Roslyn. | ||
3. **Opcode Emission:** As it traverses the tree, it converts C# statements and expressions into sequences of NeoVM instructions. | ||
|
||
## Handling C# Constructs | ||
|
||
The compiler maps various C# language features to NeoVM equivalents: | ||
|
||
* **Variable Declarations & Assignments:** Uses NeoVM stack operations (`PUSH`, `STLOC`, `LDLOC`) to manage local variables. `INITSLOT` is used at the method start to reserve space for parameters and locals. | ||
* **Arithmetic & Logical Operations:** Maps C# operators (`+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `!`, `==`, `!=`, `<`, `>`, `<=`, `>=`) to corresponding NeoVM opcodes (e.g., `ADD`, `SUB`, `MUL`, `DIV`, `MOD`, `AND`, `OR`, `XOR`, `NOT`, `NUMEQUAL`, `NUMNOTEQUAL`, `LT`, `GT`, `LE`, `GE`). The `--checked` option influences whether overflow checks (`ADDA`, `SUBA`, etc.) are emitted. | ||
* **Control Flow:** | ||
* **`if`/`else`:** Uses conditional jump opcodes (`JMPIF_L`, `JMPIFNOT_L`, `JMP_L`). | ||
* **`while`/`for`/`do-while` Loops:** Employs jump opcodes to create looping structures. `break` and `continue` statements are handled by jumping to specific target instructions. | ||
* **`switch` Statements:** Can be complex, often involving a series of comparisons and jumps or sometimes optimized using `SWITCH_L` if applicable. | ||
* **`try`/`catch`/`finally`:** Managed using NeoVM's exception handling opcodes (`TRY_L`, `ENDTRY_L`, `ENDFINALLY`). The compiler sets up exception handling contexts to route execution flow correctly. | ||
* **Method Calls:** | ||
* **Internal Calls:** Uses `CALL_L` to invoke other methods within the same contract, pushing arguments onto the stack according to the calling convention. | ||
* **Framework/Interop Calls:** Maps calls to `Neo.SmartContract.Framework` APIs (like `Runtime.Log`, `Storage.Put`, native contract methods) to specific `SYSCALL` instructions. The compiler identifies the target API by its name/hash and emits the corresponding syscall hash. | ||
* **External Contract Calls:** Uses `CALLT` and the `Contract.Call` method, requiring the target contract hash, method name, call flags, and arguments to be pushed onto the stack. | ||
* **Object Creation (`new`):** | ||
* **Simple Types:** Often involves direct stack manipulation (e.g., pushing `0` for numbers, empty byte array for strings). | ||
* **Complex Types (Structs/Classes):** Typically creates a `Struct` or `Array` on the NeoVM stack and initializes its members. | ||
* **Arrays:** Uses `NEWARRAY`, `NEWSTRUCT`, `PACK` depending on the context and type. | ||
* **Type Conversions (Casting):** May involve opcodes like `CONVERT` if a specific NeoVM type conversion is needed, or might be handled implicitly by stack manipulation. | ||
* **String/Byte Array Operations:** Maps C# string/byte array methods to NeoVM opcodes (`CAT`, `SUBSTR`, `LEFT`, `RIGHT`) or sequences of stack operations. | ||
|
||
## Mapping C# Types to NeoVM Types | ||
|
||
The compiler translates C# types into their corresponding NeoVM stack item types: | ||
|
||
| C# Type | NeoVM Type | Notes | | ||
| :---------------------- | :---------------- | :----------------------------------------- | | ||
| `void` | (No value) | | | ||
| `bool` | `Boolean` | | | ||
| `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `BigInteger` | `Integer` | | | ||
| `char` | `Integer` | Stored as its numeric UTF-16 value | | ||
| `string` | `ByteString` | UTF-8 encoded | | ||
| `byte[]` | `ByteString` | | | ||
| `object`, `dynamic` | `Any` | Represents any type | | ||
| `Array`, `List<T>`, etc. | `Array`/`Struct` | Often represented as `Array` or `Struct` | | | ||
| `Map<K,V>` | `Map` | | | ||
| Framework Types (e.g., `UInt160`, `ECPoint`) | `ByteString` | Often serialized to byte arrays | | ||
| Other Classes/Structs | `Array`/`Struct` | Usually packed into `Array` or `Struct` | | ||
|
||
## Optimization | ||
|
||
The conversion process may include basic optimizations (`--optimize Basic` or higher) like removing redundant `NOP` instructions. More advanced optimizations can further refine the generated bytecode. | ||
|
||
Understanding this conversion process helps in writing C# code that translates efficiently to NeoVM bytecode, potentially optimizing for GAS costs and execution performance. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good!
I think that some examples of a simple contract here with explanation would be something very good to add to this guideline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean results of asm, results of optimized nef, artifacts, etc. Just for a simple contract