Skip to content

Commit

Permalink
Merge pull request #102 from neo-project/dev
Browse files Browse the repository at this point in the history
merge to master
  • Loading branch information
Celia18305 authored Apr 18, 2024
2 parents 7ebc90f + 7fe450f commit 5b4fe20
Show file tree
Hide file tree
Showing 17 changed files with 606 additions and 115 deletions.
Binary file added docs/n3/develop/assets/neo-devpack-dotnet-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/n3/develop/assets/neo-devpack-dotnet-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 45 additions & 17 deletions docs/n3/develop/tool/sdk/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
`RpcClient` encapsulates the transaction construction module, which allows you to construct transactions in Neo N3 with specific parameters and methods to personalize your functions. This document introduces the relevant methods.

:::note
If you use SDK to construct a transaction that requires a signature, you need to ensure that the RpcClient obeject and the network it is connected to are configured the same way, or the transaction constructed by the SDK will not be validated in the blockchain. To do so, load Neo-CLI config.json when constructing the RpcClient object, for example:
If you use SDK to construct a transaction that requires a signature, you need to ensure that the RpcClient object and the network it is connected to are configured the same way, or the transaction constructed by the SDK will not be validated in the blockchain. To do so, load Neo-CLI config.json when constructing the RpcClient object, for example:
:::
>
> RpcClient client = new RpcClient(new Uri("http://localhost:20332"), null, null, ProtocolSettings.Load("config.json"))
Expand Down Expand Up @@ -75,6 +75,7 @@ using Neo.SmartContract.Native;
using Neo.VM;
using Neo.Wallets;
using System;
using Utility = Neo.Network.RPC.Utility;

namespace ConsoleApp1
{
Expand All @@ -88,8 +89,11 @@ namespace ConsoleApp1

private static async Task TestNep17Transfer()
{
// get the protocol settings of the network
ProtocolSettings protocolSettings = ProtocolSettings.Load("/path/to/config.testnet.json");

// choose a neo node with rpc opened
RpcClient client = new RpcClient("http://127.0.0.1:10332");
RpcClient client = new RpcClient(new Uri("http://127.0.0.1:10332"), null, null, protocolSettings);
// get the KeyPair of your account, which will pay the system and network fee
KeyPair sendKey = Utility.GetKeyPair("L53tg72Az8QhYUAyyqTQ3LaXMXBE3S9mJGGZVKHBryZxya7prwhZ");
UInt160 sender = Contract.CreateSignatureContract(sendKey.PublicKey).ScriptHash;
Expand All @@ -98,15 +102,15 @@ namespace ConsoleApp1
Signer[] cosigners = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } };

// get the scripthash of the account you want to transfer to
UInt160 receiver = Utility.GetScriptHash("NirHUAteaMr6CqWuAAMaEUScPcS3FDKebM");
UInt160 receiver = Utility.GetScriptHash("NirHUAteaMr6CqWuAAMaEUScPcS3FDKebM", protocolSettings);

// construct the script, in this example, we will transfer 1024 NEO to receiver
UInt160 scriptHash = NativeContract.NEO.Hash;
byte[] script = scriptHash.MakeScript("transfer", sender, receiver, 1024);
byte[] script = scriptHash.MakeScript("transfer", sender, receiver, 1024, null);

// initialize the TransactionManagerFactory with rpc client and magic
// fill in the TransactionManager with the script and cosigners
TransactionManager txManager = await new TransactionManagerFactory(client, 5195086)
TransactionManager txManager = await new TransactionManagerFactory(client)
.MakeTransactionAsync(script, cosigners).ConfigureAwait(false);
// add signature and sign transaction with the added signature
Transaction tx = await txManager.AddSignature(sendKey).SignAsync().ConfigureAwait(false);
Expand Down Expand Up @@ -135,6 +139,7 @@ using Neo.SmartContract.Native;
using Neo.VM;
using Neo.Wallets;
using System;
using Utility = Neo.Network.RPC.Utility;

namespace ConsoleApp1
{
Expand All @@ -148,17 +153,20 @@ namespace ConsoleApp1

private static async Task TestNep17Transfer()
{
// get the protocol settings of the network
ProtocolSettings protocolSettings = ProtocolSettings.Load("/path/to/config.testnet.json");

// choose a neo node with rpc opened
RpcClient client = new RpcClient("http://127.0.0.1:10332");
RpcClient client = new RpcClient(new Uri("http://127.0.0.1:10332"), null, null, protocolSettings);
// get the KeyPair of your account, which will pay the system and network fee
KeyPair sendKey = Utility.GetKeyPair("L53tg72Az8QhYUAyyqTQ3LaXMXBE3S9mJGGZVKHBryZxya7prwhZ");

// get the scripthash of the account you want to transfer to
UInt160 receiver = Utility.GetScriptHash("NirHUAteaMr6CqWuAAMaEUScPcS3FDKebM");
UInt160 receiver = Utility.GetScriptHash("NirHUAteaMr6CqWuAAMaEUScPcS3FDKebM", protocolSettings);

// use WalletAPI to create and send the transfer transaction
WalletAPI walletAPI = new WalletAPI(client);
Transaction tx = await walletAPI.TransferAsync(NativeContract.NEO.Hash, sendKey, receiver, 1024).ConfigureAwait(false);
Transaction tx = await walletAPI.TransferAsync(NativeContract.NEO.Hash, sendKey, receiver, 1024, null).ConfigureAwait(false);

// print a message after the transaction is on chain
WalletAPI neoAPI = new WalletAPI(client);
Expand All @@ -175,6 +183,7 @@ The following example implements a function that transfers 10 GAS to a multi-sig

```cs
using Neo;
using Neo.Cryptography.ECC;
using Neo.Network.P2P.Payloads;
using Neo.Network.RPC;
using Neo.SmartContract;
Expand All @@ -196,8 +205,11 @@ namespace ConsoleApp1

private static async Task TestToMultiTransfer()
{
// get the protocol settings of the network
ProtocolSettings protocolSettings = ProtocolSettings.Load("/path/to/config.testnet.json");

// choose a neo node with rpc opened
RpcClient client = new RpcClient("http://127.0.0.1:10332");
RpcClient client = new RpcClient(new Uri("http://127.0.0.1:10332"), null, null, protocolSettings);
// get the KeyPair of your account, which will pay the system and network fee
KeyPair sendKey = Utility.GetKeyPair("L53tg72Az8QhYUAyyqTQ3LaXMXBE3S9mJGGZVKHBryZxya7prwhZ");
UInt160 sender = Contract.CreateSignatureContract(sendKey.PublicKey).ScriptHash;
Expand All @@ -206,22 +218,28 @@ namespace ConsoleApp1
KeyPair key2 = Utility.GetKeyPair("L1bQBbZWnKbPkpHM3jXWD3E5NwK7nui2eWHYXVZPy3t8jSFF1Qj3");
KeyPair key3 = Utility.GetKeyPair("KwrJfYyc7KWfZG5h97SYfcCQyW4jRw1njmHo48kZhZmuQWeTtUHM");

// add the KeyPairs to IReadOnlyCollection<ECPoint>
IReadOnlyCollection<ECPoint> keys = new List<ECPoint>()
{
sendKey.PublicKey, key2.PublicKey, key3.PublicKey
};

// create multi-signatures contract, this contract needs at least 2 of 3 KeyPairs to sign
Contract multiContract = Contract.CreateMultiSigContract(2, sendKey.PublicKey, key2.PublicKey, key3.PublicKey);
Contract multiContract = Contract.CreateMultiSigContract(2, keys);
// get the scripthash of the multi-signature Contract
UInt160 multiAccount = multiContract.Script.ToScriptHash();

// construct the script, in this example, we will transfer 1024 GAS to multi-sign account
// in contract parameter, the amount type is BigInteger, so we need to muliply the contract factor
UInt160 scriptHash = NativeContract.GAS.Hash;
byte[] script = scriptHash.MakeScript("transfer", sender, multiAccount, 1024 * NativeContract.GAS.Factor);
byte[] script = scriptHash.MakeScript("transfer", sender, multiAccount, 1024 * NativeContract.GAS.Factor, null);

// add Signers, which is a collection of scripthashs that need to be signed
Signer[] cosigners = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } };

// initialize the TransactionManager with rpc client and magic
// fill the script and cosigners
TransactionManager txManager = await new TransactionManagerFactory(client, 5195086)
TransactionManager txManager = await new TransactionManagerFactory(client)
.MakeTransactionAsync(script, cosigners).ConfigureAwait(false);
// add signature and sign transaction with the added signature
Transaction tx = await txManager.AddSignature(sendKey).SignAsync().ConfigureAwait(false);
Expand All @@ -245,6 +263,7 @@ The following example implements a function that transfers 1024 GAS from a multi

```cs
using Neo;
using Neo.Cryptography.ECC;
using Neo.Network.P2P.Payloads;
using Neo.Network.RPC;
using Neo.SmartContract;
Expand All @@ -266,16 +285,25 @@ namespace ConsoleApp1

private static async Task TestFromMultiTransfer()
{
// get the protocol settings of the network
ProtocolSettings protocolSettings = ProtocolSettings.Load("/path/to/config.testnet.json");

// choose a neo node with rpc opened
RpcClient client = new RpcClient("http://127.0.0.1:10332");
RpcClient client = new RpcClient(new Uri("http://127.0.0.1:10332"), null, null, protocolSettings);

// get the KeyPair of your account
KeyPair receiverKey = Utility.GetKeyPair("L53tg72Az8QhYUAyyqTQ3LaXMXBE3S9mJGGZVKHBryZxya7prwhZ");
KeyPair key2 = Utility.GetKeyPair("L1bQBbZWnKbPkpHM3jXWD3E5NwK7nui2eWHYXVZPy3t8jSFF1Qj3");
KeyPair key3 = Utility.GetKeyPair("KwrJfYyc7KWfZG5h97SYfcCQyW4jRw1njmHo48kZhZmuQWeTtUHM");

// add the KeyPairs to IReadOnlyCollection<ECPoint>
IReadOnlyCollection<ECPoint> keys = new List<ECPoint>()
{
receiverKey.PublicKey, key2.PublicKey, key3.PublicKey
};

// create multi-signature contract, this contract needs at least 2 of 3 KeyPairs to sign
Contract multiContract = Contract.CreateMultiSigContract(2, receiverKey.PublicKey, key2.PublicKey, key3.PublicKey);
Contract multiContract = Contract.CreateMultiSigContract(2, keys);
// get the scripthash of the multi-signature Contract
UInt160 multiAccount = multiContract.Script.ToScriptHash();

Expand All @@ -284,17 +312,17 @@ namespace ConsoleApp1
// construct the script, in this example, we will transfer 1024 GAS to multi-sign account
// in contract parameter, the amount type is BigInteger, so we need to muliply the contract factor
UInt160 scriptHash = NativeContract.GAS.Hash;
byte[] script = scriptHash.MakeScript("transfer", multiAccount, receiver, 1024 * NativeContract.GAS.Factor);
byte[] script = scriptHash.MakeScript("transfer", multiAccount, receiver, 1024 * NativeContract.GAS.Factor, null);

// add Signers, which is a collection of scripthashs that need to be signed
Signer[] cosigners = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = multiAccount } };

// initialize the TransactionManager with rpc client and magic
// fill the script and cosigners
TransactionManager txManager = await new TransactionManagerFactory(client, 5195086)
TransactionManager txManager = await new TransactionManagerFactory(client)
.MakeTransactionAsync(script, cosigners).ConfigureAwait(false);
// add signature and sign transaction with the added signature
Transaction tx = await txManager.AddMultiSig(new KeyPair[]{receiverKey, key2}, 2, receiverKey.PublicKey, key2.PublicKey, key3.PublicKey)
Transaction tx = await txManager.AddMultiSig(new KeyPair[] { receiverKey, key2 }, 2, receiverKey.PublicKey, key2.PublicKey, key3.PublicKey)
.SignAsync().ConfigureAwait(false);

// broadcasts the transaction over the Neo network.
Expand Down
159 changes: 159 additions & 0 deletions docs/n3/develop/write/1_dotnet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Using Neo Devpack Dotnet

Designed for developers, Neo Devpack Dotnet is a comprehensive toolkit for creating Neo contracts using .net. It offers convenient contract project templates and a compiler.

When developing and deploying a contract, the typical process is the following:

- Installing a project template
- Creating a project using templates
- Writing a contract
- Compiling the contract
- Deploying and testing it

This document covers the usage of project templates and the compiler. For further details on writing and deploying your contract, refer to the subsequent sections.

:::note

- Ensure that you install project templates and compilers with matching or the most recent versions when setting them up.

- If it's been a long while since you last updated your project templates and compiler, make sure to update both when using them again.

:::

## Neo.SmartContract.Template

Neo.SmartContract.Template is a project template used when developing Neo smart contracts. After installing the template, you can create a Neo smart contract project using either the Terminal or Visual Studio.

### Install the template

```
dotnet new install Neo.SmartContract.Template
```

### List all dotnet templates

```
dotnet new list
```

### Uninstall the template

```
dotnet new uninstall Neo.SmartContract.Template
```

### Update the template

```
dotnet new update Neo.SmartContract.Template
```

### Create a project using templates with Terminal

```
dotnet new neocontract
```

The project name defaults to the name of the current directory, you can also specify the project name with `-n, --name <name>`, e.g. `dotnet new neocontract -n MyFirstContract`.

### Create a project using templates with Visual Studio

In the Visual Studio interface, create a new project, Neo.SmartContract.Template, as shown in the following screenshots:

![](../assets/neo-devpack-dotnet-1.png)

![](../assets/neo-devpack-dotnet-2.png)



## Neo.Compiler.CSharp

Neo.Compiler.CSharp (nccs) is the Neo smart contract compiler that compiles the C# language into NeoVM executable OpCodes.

In the project file of the contract project template, you can find the following code,


```xml
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Message Text="Start NeoContract converter, Source File: $(ProjectPath)" Importance="high"></Message>
<Exec Command="nccs $(BaseNameArgument) $(NullableArgument) $(CheckedArgument) $(DebugArgument) &quot;$(ProjectPath)&quot;" />
</Target>
```

which is designed to trigger a secondary compilation with `nccs` after a successful C# compilation. This secondary compilation compiles it to a `nef` file and outputs the `manifest.json` file.

Among them, .nef stands for NEO Executable Format, which mainly contains the contracts's executable code. The specific structure can be found on [GitHub](https://github.com/neo-project/neo/blob/master/src/Neo/SmartContract/NefFile.cs).

manifest.json represents the manifest of a smart contract. When a smart contract is deployed, it must explicitly declare the features and permissions it will use.

When running, it will be restricted by its declared list of features and permissions, and cannot exhibit any behavior outside the scope of the list.

### Install the compiler

```
dotnet tool install --global Neo.Compiler.CSharp
```

### List all dotnet tools

```
dotnet tool list
```

### Uninstall the compiler

```
dotnet tool uninstall --global Neo.Compiler.CSharp
```

### Update the compiler

```
dotnet tool update --global Neo.Compiler.CSharp
```

### Compile the contract file with Terminal

In the Terminal interface, go to the project path and run the following command to build your contract:

```
dotnet build
```

or

```
nccs
```

Related contract files are outputted under `bin\sc` path in the contract project directory.

### Compile the contract file with Visual Studio

In the Visual Studio interface, click Build -> Build Solution (Ctrl + Shift + B).

## Versioning tips

- After successfully creating the project, open it and check if the version of the NuGet package `Neo.SmartContract.Framework` matches the version of `Neo.Compiler.CSharp`. If the compiler is up-to-date but Neo.SmartContract.Framework is not, please manually update it to ensure the proper compilation of the project.

- If you're working on an older contract project, make sure to compile it using the appropriate compiler version.

- If you are updating a contract project that is quite old, ensure that you have upgraded both the NuGet package `Neo.SmartContract.Framework` and the compiler to the latest versions, and also make necessary modifications to the contract code.

- For the most current way of writing contract code, see this document or [GitHub](https://github.com/neo-project/neo-devpack-dotnet/tree/master/examples). Among other things, the example contracts in GitHub may contain code for the upcoming version (unreleased) of the template and compiler.

## References

[NuGet (Neo.SmartContract.Template)](https://www.nuget.org/packages/Neo.SmartContract.Template)

[NuGet (Neo.Compiler.CSharp)](https://www.nuget.org/packages/Neo.Compiler.CSharp)

[GitHub (Neo-Devpack-Dotnet)](https://github.com/neo-project/neo-devpack-dotnet)

[GitHub (example contracts)](https://github.com/neo-project/neo-devpack-dotnet/tree/master/examples)

Contract template for community maintenance:

- [Neo3.SmartContract.Templates](https://www.nuget.org/packages/Neo3.SmartContract.Templates) by: shuaishuimen

- [NeoEvents.SmartContract.Templates](https://www.nuget.org/packages/NeoEvents.SmartContract.Templates) by: cschuchardt
Loading

0 comments on commit 5b4fe20

Please sign in to comment.