Giter VIP home page Giter VIP logo

neo-devpack-dotnet's People

Contributors

annashaleva avatar ashuaidehao avatar belane avatar bettybao1209 avatar chenzhitong avatar cloud8little avatar cschuchardt88 avatar devhawk avatar doubiliu avatar erikzhang avatar hecate2 avatar igormcoelho avatar jim8y avatar kolevatykh avatar lightszero avatar lock9 avatar prodog avatar qiao-jin avatar ravenxce avatar shargon avatar shawnyun avatar superboyiii avatar thacryba avatar tommo-l avatar vikkkko avatar vncoelho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

neo-devpack-dotnet's Issues

Debug neon in master2x

@devhawk I was not able to debug neon in master 2x after merge #166 , maybe we need to define

<TargetFramework>netcoreapp3.1</TargetFramework> as default in the csproj.

I need to do these changes if I want to debug it

image

Cannot serialize struct

Hi! I'm expecting an issue with struct serialization. How can I hadle it? Or which info i should provide?
System.Exception: unknown call: System.Byte[] Neo.SmartContract.Framework.Helper::Serialize(System.Object)

Sample code :
struct Test { public int a; } static void TestStruct() { var t = new Test(); t.a = 1; var x = t.Serialize(); }

Neon should be able to compile from the source

For developers we have two steps in order to compile from a c# code.

  • First we need to compile the c# into .net assembly.
  • Then compile it in neon.

I want to allow neon to do all in one step.

Proposed solution: #131

Cannot use StorageMap helpers

The c# compiler seems to be trying to compile the methods in https://github.com/neo-project/neo-devpack-dotnet/blob/master/Neo.SmartContract.Framework/Services/Neo/Helper.cs?

How is it meant to be used?

Code: storageMap.Get("myaddr"); gives
Error:

Neo.SmartContract.MyProject::MyMethod(System.Byte[])::IL_0015 Call 
System.Byte[] Neo.SmartContract.Framework.Services.Neo.Helper::Get(Neo.SmartContract.Framework.Services.Neo.StorageMap,System.String) ---> 
System.Exception: unknown call: System.Byte[] Neo.SmartContract.Framework.Services.Neo.Helper::Get(Neo.SmartContract.Framework.Services.Neo.StorageMap,System.String)

in File: CONVERTTASK

StorageMap optimizations

In every get, put, or delete, we convert the string to byte[] and concat it with the prefix 0x00, is better to concat this at the initialization, only once.

Also should be added two overloads, for allow one byte and byte[] parameters

byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
Storage.Delete(map.Context, k);
}
public static void Delete(this StorageMap map, string key)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());
Storage.Delete(map.Context, k);
}
public static byte[] Get(this StorageMap map, byte[] key)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
return Storage.Get(map.Context, k);
}
public static byte[] Get(this StorageMap map, string key)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());
return Storage.Get(map.Context, k);
}
public static void Put(this StorageMap map, byte[] key, byte[] value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
Storage.Put(map.Context, k, value);
}
public static void Put(this StorageMap map, byte[] key, BigInteger value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
Storage.Put(map.Context, k, value);
}
public static void Put(this StorageMap map, byte[] key, string value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key);
Storage.Put(map.Context, k, value);
}
public static void Put(this StorageMap map, string key, byte[] value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());
Storage.Put(map.Context, k, value);
}
public static void Put(this StorageMap map, string key, BigInteger value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());
Storage.Put(map.Context, k, value);
}
public static void Put(this StorageMap map, string key, string value)
{
byte[] k = map.Prefix.AsByteArray().Concat(new byte[] { 0 }).Concat(key.AsByteArray());

Port Contract metadata attributes to master branch

#148 adds new custom attributes to allow developers to specify that their contract uses storage or dynamic invoke. NEON for neo 3 should support these attributes unless the compiler can determine the need for storage/dynamic invoke automatically

[syntax sugar]Add support of hashtable

Abstract

This is syntax sugar.with support of hashtable seems much convenience to save/read in smartcontract.

Motivation

I think use hashTable to save/read is much convenience , this can reduce the complexity of contract development and easier to understand

Specification

this is the sample, if with no hashTable, we have to

        public static object Main(string operation, params object[] args)
        {
            switch (operation)
            {
                ...
            }
        }

        private static byte[] Query(string domain)
        {
            return Storage.Get(Storage.CurrentContext, domain);   <=== hard to read and coding
        }

        private static bool Register(string domain, byte[] owner)
        {
            Storage.Put(Storage.CurrentContext, domain, owner);  <=== hard to read and coding
            return true;
        }

if we have hashTable ,we can use hashTable name ='domainTable' as the prefix to save/read the contract data.

        public static object Main(string operation, params object[] args)
        {
            Hashtable domainTable=new Hashtable(); 
            switch (operation)
            {
                ...
            }
        }

        private static byte[] Query(string domain)
        {
            return domainTable[domain]    <=== easy to use and understand
        }

        private static bool Register(string domain, byte[] owner)
        {
            domainTable[domain]=owner   <=== easy to use and understand
            return true;
        }

Rationale

na

Backwards Compatibility

na

Test Cases

na

Implementation

na

Cannot use Map [Compiler Error]

I am trying to use Map objects and to save them using Storage.Put and calling .Serialize() and .Deserialize() when needed.

however I run into this error

System.Exception: error:System.String TradeItemsContract.TradeItemsContract::NewTrade(System.Byte[],System.String,System.String)::IL_00E5 Stsfld  ---> System.Exception: unsupported instruction Stsfld	TradeItemsContract	
C:\Users\MyUser\Desktop\TradeItemsContract\TradeItemsContract\CONVERTTASK		

The method is

//the class has trade_count static uint variable, which is modified
static uint trade_count = 0;

//also Now is a static variable but is readonly so it's ok

public static string NewTrade(byte[] user_hash, string item_id_sale, string item_id_want)
{
            Map<string, uint> itemMap;
            Map<string, object> userMap;
            Map<string, object> tradeMap;

            string user_key = "user_" + user_hash.AsString();
            string trade_key = "trade_" + trade_count;

            if (!Runtime.CheckWitness(user_hash))
                return "invalid";

            var userMapTmp = Storage.Get(Storage.CurrentContext, user_key);
            if (userMapTmp == null)
                userMap = new Map<string, object>();
            else
                userMap = (Map<string, object>)userMapTmp.Deserialize();

            if (!userMap.HasKey("owned_items"))
                return "invalid";

            itemMap = (Map<string, uint>)userMap["owned_items"];
            
            if (!itemMap.HasKey(item_id_sale))
                return "invalid";

            var temp_quantity = itemMap[item_id_sale];
            if (temp_quantity == 0)
                return "invalid";

            trade_count++;
            var tradeMapTmp = Storage.Get(Storage.CurrentContext, trade_key);
            if (tradeMapTmp == null)
                tradeMap = new Map<string, object>();
            else
                tradeMap = (Map<string, object>)tradeMapTmp.Deserialize();

            tradeMap["status"] = TRADE_OPEN;
            tradeMap["seller"] = user_hash.AsString();
            tradeMap["sells_item"] = item_id_sale;
            tradeMap["wants_item"] = item_id_want;
            tradeMap["buyer"] = "none";
            tradeMap["opened_at"] = Now;

            // puts on hold the traded item
            itemMap[item_id_sale] = temp_quantity - 1;

            // setting back maps
            userMap["owned_items"] = itemMap;

            // saving trade and buyer situation
            Storage.Put(Storage.CurrentContext, user_key, userMap.Serialize());
            Storage.Put(Storage.CurrentContext, trade_key, tradeMap.Serialize());

            return trade_count.Serialize().AsString();
}

Can anybody help me out?

OOM abusing large arrays

Problem

Local out of memory abusing large arrays

image

Also, the constructor's detection need to be improved because is bypaseable using cctor as class name

image

POC:

namespace Neo.Compiler.MSIL.TestClasses
{
    class cctor : SmartContract.Framework.SmartContract
    {
        public static void Main(string method, object[] args)
        {
            int size = 2147483647;
            byte[] test1 = new byte[size];
            byte[] test2 = new byte[size];
        }
    }
}

neon can't compile netstandard2.0 assemblies

HelloWorld sample contract from neo-project/examples repo targets .NET Framework v4.6.2. I modified the project file to generate a netstandard2.0 dll and I got the following error results on the console

PS> dotnet build
Microsoft (R) Build Engine version 16.2.32702+c4012a063 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 147.45 ms for C:\Users\harry\Source\neo\official\examples\csharp\HelloWorld\HelloWorld.csproj.
  HelloWorld -> C:\Users\harry\Source\neo\official\examples\csharp\HelloWorld\bin\Debug\netstandard2.0\HelloWorld.dll
  Neo.Compiler.MSIL console app v2.4.1.0
EXEC : Convert error : System.Exception: error:System.Boolean Neo.SmartContract.HelloWorld::Main(System.String,System.Object[])::IL_000B Call System.Void Neo.SmartContract.Framework.Services.Neo.Storage::Put(System.String,System.String) ---> System.NullReferenceException: Object reference not set to an instance of an object. [C:\Users\harry\Source\neo\official\examples\csharp\HelloWorld\HelloWorld.csproj]
     at Neo.Compiler.MSIL.ModuleConverter.TryInsertMethod(NeoModule outModule, MethodDefinition method) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\MSIL\Conv_Multi.cs:line 967
     at Neo.Compiler.MSIL.ModuleConverter._ConvertCall(OpCode src, NeoMethod to) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\MSIL\Conv_Multi.cs:line 795
     at Neo.Compiler.MSIL.ModuleConverter.ConvertCode(ILMethod method, OpCode src, NeoMethod to) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\MSIL\Converter.cs:line 884
     at Neo.Compiler.MSIL.ModuleConverter.ConvertMethod(ILMethod from, NeoMethod to) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\MSIL\Converter.cs:line 454
     --- End of inner exception stack trace ---
     at Neo.Compiler.MSIL.ModuleConverter.ConvertMethod(ILMethod from, NeoMethod to) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\MSIL\Converter.cs:line 458
     at Neo.Compiler.MSIL.ModuleConverter.Convert(ILModule _in, ConvOption option) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\MSIL\Converter.cs:line 197
     at Neo.Compiler.Program.Main(String[] args) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\Program.cs:line 88
C:\Users\harry\Source\neo\official\examples\csharp\Directory.Build.targets(4,5): error MSB3073: The command "dotnet C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\bin\Debug\netcoreapp2.0\publish\neon.dll HelloWorld.dll" exited with code -1. [C:\Users\harry\Source\neo\official\examples\csharp\HelloWorld\HelloWorld.csproj]

Build FAILED.

EXEC : Convert error : System.Exception: error:System.Boolean Neo.SmartContract.HelloWorld::Main(System.String,System.Object[])::IL_000B Call System.Void Neo.SmartContract.Framework.Services.Neo.Storage::Put(System.String,System.String) ---> System.NullReferenceException: Object reference not set to an instance of an object. [C:\Users\harry\Source\neo\official\examples\csharp\HelloWorld\HelloWorld.csproj]
C:\Users\harry\Source\neo\official\examples\csharp\Directory.Build.targets(4,5): error MSB3073: The command "dotnet C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\bin\Debug\netcoreapp2.0\publish\neon.dll HelloWorld.dll" exited with code -1. [C:\Users\harry\Source\neo\official\examples\csharp\HelloWorld\HelloWorld.csproj]
    0 Warning(s)
    2 Error(s)

Smart contract doesn't support object array

It seems that neo-compiler & neo-vm don't support object array in smart contract currently, i.e.

using Neo.SmartContract.Framework;
using System.Numerics;

namespace TestArray
{
    public class Contract1 : SmartContract
    {
        public static object Main(string operation, object[] args)
        {
            State[] states = new State[] { new State() };
            for (var i = 0; i < 1; i++)
            {
                State state = states[i];
            }
            return true;
        }

        public struct State
        {
            public byte[] from;
            public byte[] to;
            public BigInteger amount;
        }
    }
}

The simple smart contract will report an error if built in release mode:

IL_000D Ldelema  ---> System.Exception: unsupported instruction Ldelema

After researching I found out this is due to some lack of functionality in func neo-compiler\neon\MSIL\Converter.ConvertCode:

case CodeEx.Switch:
{
    throw new Exception("need neo.VM update.");
    //var addrdata = new byte[src.tokenAddr_Switch.Length * 2 + 2];
    //var shortaddrcount = (UInt16)src.tokenAddr_Switch.Length;
    //var data = BitConverter.GetBytes(shortaddrcount);
    //addrdata[0] = data[0];
    //addrdata[1] = data[1];
    //var code = _Convert1by1(VM.OpCode.SWITCH, src, to, addrdata);
    //code.needfix = true;
    //code.srcaddrswitch = new int[shortaddrcount];
    //for (var i = 0; i < shortaddrcount; i++)
    //{
    //    code.srcaddrswitch[i] = src.tokenAddr_Switch[i];
    //}
    }
    break;

This piece of code is commented out because VM.OpCode.SWITCH and corresponding logic is not yet defined. By blaming the code it seems this piece of code is inserted in 2017. I suppose this pending functionality might be forgotten?

Furthermore, even if it can be built successfully under debug mode, still an error would occur if run on chain. After debugging it seems that there is an array bound problem in func neo-vm\src\neo-vm\ExecutionEngine.ExecuteInstruction, case OpCode.PICKITEM.

Could anyone have a look at this problem?

Getnep5balances, balance won't change when a transaction is not `transfer`.

Describe the bug
Getnep5balances, balance won't change when a tx is not transfer. Then, make a transfer tx, the gas balance value will return to normal.

To Reproduce
1.open wallet 6.json, deploy a smartcontract, list asset, gas balance = 8.9850761
image

2.rpc getnep5balances, gas balance didn't change, gas balance = 10
image

3.make a transfer transaction, list asset, gas balance = 6.9723922
image

4.rpc getnep5balances, gas balance changed, gas balance = 6.9723922
image

Distribute neon as a .NET Global Tool

the current model of distributing the NEON compiler requires many steps for the developer. .NET Core supports global tools which are easy to install and automatically are added to the path. Basically, all the developer would have to do would be

$ dotnet tool install -g Neo.Compiler.MSIL

we might also want to change the package name to just "neon"

Fix negative shift operator for BigInteger

Man, this compiler nearly gave me a heart attack...
This code doesn't compile:

       public static BigInteger Main() {
            BigInteger x = 8;
            BigInteger b = 0;
            b += x;
            b += x << 1;
            b += x << -1;
            return b;
        }

And this one compiles "fine", but converts shift << -1 to << 31...

       public static BigInteger Main() {
            int x = 8;
            BigInteger b = 0;
            b += x;
            b += x << 1;
            b += x << -1;
            return b;
        }

Took some time to realize that: neo-project/neo-vm#167

Create NEP-5 template for Neo3

NEP-5

  • Mint tokens based in GAS / Token input
  • Transfer tokens to smart contract
  • Transfer funds from smart contract (verification trigger)
  • Create new NEP-5 template (reference code)

From Native NEP-5

  • Allow contract to accept Native Gas
  • Allow contract to accept Native Neo
  • Transfer funds to smart contract using MultiSig
  • Withdraw funds from smart contract using MultiSig

From Neo-cli

  • Neo-cli: Allow NEP-5 contract to be deployed and called

Note: This is not an 'ICO' template, only NEP-5 (for now)

Negative shift with integers

I think not allowing negative numbers in SHL / SHR is not enough (neo-project/neo-vm@8f19980).

The compiler is doing the shift with 31 when it's -1. I tried with this smart contract

 class Contract_shift : SmartContract.Framework.SmartContract
    {
        public static object Main()
        {
            //int v = 8;
            System.Numerics.BigInteger v = 8;
            var v1 = v << -1;
            return v1;
        }
}

And this is the summary.

With integer:

IL

image

NEF

0000=>0000 PUSHF           []//static var(0)
0001=>0001 NEWARRAY        []//(0)
0002=>0002 TOALTSTACK      []//(0)
0003=>0003 PUSH3           []//begincode(0)
0004=>0004 NEWARRAY        []//(0)
0005=>0005 TOALTSTACK      []//(0)
0006=>0006 NOP             []//(6)
0007=>0007 PUSH8           []//(7)
0008=>0008 DUPFROMALTSTACK []
0009=>0009 PUSHF           []
000A=>000A PUSH2           []
000B=>000B ROLL            []
000C=>000C SETITEM         []
000D=>000D DUPFROMALTSTACK []//(9)
000E=>000E PUSHF           []
000F=>000F PICKITEM        []
0010=>0010 PUSHBYTES1      [1F] HEX:1F   <--- 31 in decimal
0012=>0012 SHL             []
0013=>0013 DUPFROMALTSTACK []
0014=>0014 PUSH1           []
0015=>0015 PUSH2           []
0016=>0016 ROLL            []
0017=>0017 SETITEM         []
0018=>0018 DUPFROMALTSTACK []//(10)
0019=>0019 PUSH1           []
001A=>001A PICKITEM        []
001B=>001B DUPFROMALTSTACK []
001C=>001C PUSH2           []
001D=>001D PUSH2           []
001E=>001E ROLL            []
001F=>001F SETITEM         []
0020=>0020 JMP             [0300] HEX:0300
0023=>0023 DUPFROMALTSTACK []//(11)
0024=>0024 PUSH2           []
0025=>0025 PICKITEM        []
0026=>0026 NOP             []
0027=>0027 FROMALTSTACK    []//endcode(0)
0028=>0028 DROP            []//(0)
0029=>0029 RET             []

With big integers

IL

image

NEF

0000=>0000 PUSHF           []//static var(0)
0001=>0001 NEWARRAY        []//(0)
0002=>0002 TOALTSTACK      []//(0)
0003=>0003 PUSH3           []//begincode(0)
0004=>0004 NEWARRAY        []//(0)
0005=>0005 TOALTSTACK      []//(0)
0006=>0006 NOP             []//(6)
0007=>0007 PUSH8           []//(8)
0008=>0008 DUPFROMALTSTACK []
0009=>0009 PUSHF           []
000A=>000A PUSH2           []
000B=>000B ROLL            []
000C=>000C SETITEM         []
000D=>000D DUPFROMALTSTACK []//(9)
000E=>000E PUSHF           []
000F=>000F PICKITEM        []
0010=>0010 PUSHM1          [] <--- -1 is good!
0011=>0011 SHL             []
0012=>0012 DUPFROMALTSTACK []
0013=>0013 PUSH1           []
0014=>0014 PUSH2           []
0015=>0015 ROLL            []
0016=>0016 SETITEM         []
0017=>0017 DUPFROMALTSTACK []//(10)
0018=>0018 PUSH1           []
0019=>0019 PICKITEM        []
001A=>001A DUPFROMALTSTACK []
001B=>001B PUSH2           []
001C=>001C PUSH2           []
001D=>001D ROLL            []
001E=>001E SETITEM         []
001F=>001F JMP             [0300] HEX:0300
0022=>0022 DUPFROMALTSTACK []//(11)
0023=>0023 PUSH2           []
0024=>0024 PICKITEM        []
0025=>0025 NOP             []
0026=>0026 FROMALTSTACK    []//endcode(0)
0027=>0027 DROP            []//(0)
0028=>0028 RET             []

Before the SHL Opcode, we push 0xFF (31) in the stack, instead of -1

0010=>0010 PUSHBYTES1      [1F] HEX:1F   <--- 31 in decimal
0012=>0012 SHL             []

Could you take a look to this bug @lightszero ?

AsByteArray() isn't able to convert BigInteger to ByteArray

When I test nep5 sc, I'd like to put 0 into account storage when balanceOf return null, so I write as below:

        [DisplayName("BalanceOf")]
        public static BigInteger BalanceOf(byte[] account)
        {
            if (account.Length != 20)
                throw new InvalidOperationException("The parameter account SHOULD be 20-byte addresses");
            var balance = Storage.Get(Storage.CurrentContext, account);
            BigInteger zero = 0;
            byte[] byteZero = zero.AsByteArray();
            if (balance is null)
            {
                Storage.Put(Storage.CurrentContext, account, byteZero);
            }
            return Storage.Get(Storage.CurrentContext, account).AsBigInteger();
        }

Then I found this byteZero is not a byteArray but still return BigInteger 0 which cause RPC getBalance return 0 if one of addresses in a wallet doesn't have balance.
Then I tried another style, it works well. This means AsByteArray() here isn't work normally.
image
Then I found AsByteArray() isn't able to conver BigInteger to ByteArray but just transfer it to VM. This makes me a little confused. Since native C# conversion method ToByteArray() isn't able to be used in sc.framework, we don't have a method support BigInteger to ByteArray on sc framework.
@erikzhang @lightszero @shargon

Update Visual Studio Version

Hello,
The current DevPack is not compatible with the latest version of the compiler.

I spoke with @igormcoelho and it seems that the version I'm using is outdated, but it is the latest available in VisualStudio.
Here is the error:

Neo.Compiler.MSIL console app v2.3.0.9
Convert Error:System.Exception: error:System.Void SimpliPay.BankDao::PersistRegularAccount(System.Byte[],System.Byte[])::IL_0007 Call System.Byte[] Neo.SmartContract.Framework.Helper::Concat(System.Byte[],System.Byte[]) ---> System.InvalidCastException: Unable to cast object of type 'System.Byte' to type 'Mono.Cecil.CustomAttributeArgument[]'.
   at Neo.Compiler.MSIL.ModuleConverter.IsOpCall(MethodDefinition defs, OpCode[]& opcodes)
   at Neo.Compiler.MSIL.ModuleConverter._ConvertCall(OpCode src, NeoMethod to)
   at Neo.Compiler.MSIL.ModuleConverter.ConvertCode(ILMethod method, OpCode src, NeoMethod to)
   at Neo.Compiler.MSIL.ModuleConverter.ConvertMethod(ILMethod from, NeoMethod to)
   --- End of inner exception stack trace ---
   at Neo.Compiler.MSIL.ModuleConverter.ConvertMethod(ILMethod from, NeoMethod to)
   at Neo.Compiler.MSIL.ModuleConverter.Convert(ILModule _in, ConvOption option)
   at Neo.Compiler.Program.Main(String[] args)

Thanks

Use a Command Line Processing Library for NEON (master + master 2.x)

As NEON evolves, it would be useful for it to support more command line options. Instead of manually processing these options, we should use a library.

Possible library suggestions:

  • natemcmaster/CommandLineUtils - a mature command line processing library originally forked from now-defunct Microsoft.Extensions.CommandLineUtils project. Neo-Express uses this library.
  • dotnet/command-line-api a new (and still immature) command line processing library that appears to be slated to become the official command line processing solution from Microsoft for .NET

Update master 2.x version numbers for NEON and Smart Contract Framework

We need to ship a new version of NEON (packaged as a global tool as per #159) and the smart contract framework. As part of that release, these packages need new version numbers. Since these tools are in maintenance mode, I believe we should continue to update the version numbers manually.

  • current version of Neo.SmartContract.Framework is v2.9.3.1. I recommend moving to v2.10

    • as per Semantic Versioning we should bump the minor version number because we have added backward compatible changes
  • current version of Neo.Compiler.MSIL is v2.4.1.1. I recommend moving to v2.6.

    • Again, as per Semantic Versioning we should bump the minor version number because we have added backward compatible changes
    • The current version of Neo.neon-de is v2.5.11. Even though neon-de is a separate fork, it seems reasonable to bump neon an extra minor version number to make it clear that neon is the latest and greatest version of the tool to use

NEON doesn't generate correct ABI information for events with type parameters

If the delegate is specified without type parameters, the abi.json file gets the correct ABI information

public delegate void AlertDelegate(string one, string two);
public static event AlertDelegate Alert;
{
    "name":"Alert",
    "parameters":
    [
        { "name":"one", "type":"String" },
        { "name":"two", "type":"String" }
    ],
    "returntype":"Void"
}

If the event is specified with a delegate using type parameters, the ABI information is missing

public static event Action<string, string> Alert;
{
    "name":"Alert",
    "parameters":
    [
    ],
    "returntype":"Unknown:"
}

Can't run in VS2019

image
在 VS2019 中编译智能合约会报错,解决办法是编译 neo-devpack-dotnet 项目,将生成的 Neo.SmartContract.Framework.dll 替换掉原有的文件。

Compile smart contract error in VS2019, solution is to compile the neo-devpack-dotnet project, and replace Neo.SmartContract.Framework.dll file to the existing file.

Problems publishing an exe file

Using this guide https://dotnetcoretutorials.com/2019/06/20/publishing-a-single-exe-file-in-net-core-3-0/

dotnet publish -c Release /p:PublishSingleFile=true -r win-x64

I obtained the error as shown below

Microsoft (R) Build Engine version 16.2.32702+c4012a063 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

C:\Sources\Neo\neo-devpack-dotnet\src\Neo.Compiler.MSIL\Neo.Compiler.MSIL.csproj : error NU1605: Detected package downgrade: System.IO.FileSystem.Primitives from 4.3.0 to 4.0.1. Reference the package directly from the project to select a different version.
C:\Sources\Neo\neo-devpack-dotnet\src\Neo.Compiler.MSIL\Neo.Compiler.MSIL.csproj : error NU1605:  Neo.Compiler.MSIL -> Mono.Cecil 0.10.3 -> System.IO.FileSystem 4.0.1 -> runtime.win.System.IO.FileSystem 4.3.0 -> System.IO.FileSystem.Primitives (>= 4.3.0)
C:\Sources\Neo\neo-devpack-dotnet\src\Neo.Compiler.MSIL\Neo.Compiler.MSIL.csproj : error NU1605:  Neo.Compiler.MSIL -> Mono.Cecil 0.10.3 -> System.IO.FileSystem.Primitives (>= 4.0.1)
  Restore failed in 594.52 ms for C:\Sources\Neo\neo-devpack-dotnet\src\Neo.Compiler.MSIL\Neo.Compiler.MSIL.csproj.

Also, we should provide releases for make this procedure easier for devs

Invoke deploy method on nep5 sc, return fault (latest master)

Using the latest master branch of neo. neo-vm, neo-cli, neo-devpack-dotnet, I tried to deploy a nep-5 sc on my privnet, it was built and deployed successfully.
image
image
I also invoke static method and got correct return value. However when I invoke deploy method, it returned fault straightly.
image
My contract:

using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Services.Neo;
using Neo.SmartContract.Framework.Services.System;
using System;
using System.ComponentModel;
using System.Numerics;

namespace NEP5
{
    public class NEP5 : SmartContract
    {
        [DisplayName("transfer")]
        public static event Action<byte[], byte[], BigInteger> Transferred;

        private static readonly byte[] Owner = "NeHNBbeLNtiCEeaFQ6tLLpXkr5Xw6esKnV".ToScriptHash(); //Owner Address
        private static readonly BigInteger TotalSupplyValue = 10000000000000000;

        public static object Main(string method, object[] args)
        {
            if (Runtime.Trigger == TriggerType.Verification)
            {
                return Runtime.CheckWitness(Owner);
            }
            else if (Runtime.Trigger == TriggerType.Application)
            {
                var callscript = ExecutionEngine.CallingScriptHash;

                if (method == "balanceOf") return BalanceOf((byte[])args[0]);

                if (method == "decimals") return Decimals();

                if (method == "deploy") return Deploy();

                Runtime.Notify("aaa");

                if (method == "name") return Name();

                if (method == "symbol") return Symbol();

                if (method == "supportedStandards") return SupportedStandards();

                if (method == "totalSupply") return TotalSupply();

                if (method == "transfer") return Transfer((byte[])args[0], (byte[])args[1], (BigInteger)args[2], callscript);
            }
            return false;
        }

        [DisplayName("balanceOf")]
        public static BigInteger BalanceOf(byte[] account)
        {
            if (account.Length != 20)
                throw new InvalidOperationException("The parameter account SHOULD be 20-byte addresses.");
            StorageMap asset = Storage.CurrentContext.CreateMap(nameof(asset));
            return asset.Get(account).AsBigInteger();
        }
        [DisplayName("decimals")]
        public static byte Decimals() => 8;

        private static bool IsPayable(byte[] to)
        {
            var c = Blockchain.GetContract(to);
            return c == null || c.IsPayable;
        }

        [DisplayName("deploy")]
        public static bool Deploy()
        {
            if (TotalSupply() != 0) return false;
            StorageMap contract = Storage.CurrentContext.CreateMap(nameof(contract));
            contract.Put("totalSupply", TotalSupplyValue);
            StorageMap asset = Storage.CurrentContext.CreateMap(nameof(asset));
            asset.Put(Owner, TotalSupplyValue);
            Transferred(null, Owner, TotalSupplyValue);
            return true;
        }

        [DisplayName("name")]
        public static string Name() => "Best Coin"; //name of the token

        [DisplayName("symbol")]
        public static string Symbol() => "BC"; //symbol of the token

        [DisplayName("supportedStandards")]
        public static string[] SupportedStandards() => new string[] { "NEP-5", "NEP-7", "NEP-10" };

        [DisplayName("totalSupply")]
        public static BigInteger TotalSupply()
        {
            StorageMap contract = Storage.CurrentContext.CreateMap(nameof(contract));
            return contract.Get("totalSupply").AsBigInteger();
        }
#if DEBUG
        [DisplayName("transfer")] //Only for ABI file
        public static bool Transfer(byte[] from, byte[] to, BigInteger amount) => true;
#endif
        //Methods of actual execution
        private static bool Transfer(byte[] from, byte[] to, BigInteger amount, byte[] callscript)
        {
            //Check parameters
            if (from.Length != 20 || to.Length != 20)
                throw new InvalidOperationException("The parameters from and to SHOULD be 20-byte addresses.");
            if (amount <= 0)
                throw new InvalidOperationException("The parameter amount MUST be greater than 0.");
            if (!IsPayable(to))
                return false;
            if (!Runtime.CheckWitness(from) && from.AsBigInteger() != callscript.AsBigInteger())
                return false;
            StorageMap asset = Storage.CurrentContext.CreateMap(nameof(asset));
            var fromAmount = asset.Get(from).AsBigInteger();
            if (fromAmount < amount)
                return false;
            if (from == to)
                return true;

            //Reduce payer balances
            if (fromAmount == amount)
                asset.Delete(from);
            else
                asset.Put(from, fromAmount - amount);

            //Increase the payee balance
            var toAmount = asset.Get(to).AsBigInteger();
            asset.Put(to, toAmount + amount);

            Transferred(from, to, amount);
            return true;
        }
    }
}

sc.zip

Two convert cases will fail

One case

public static bool CheckNullConvertToBigInteger(string code)
{
       var m = Storage.Get(code);
       var k = m?.AsBigInteger();  // <---- this convert will throw ex, but if we remove the `?`, it will not throw
       return k == null;
}

Then the compiler will throw the following exceptions

 消息: 
    Initialization method Neo.Compiler.MSIL.UnitTest_NULL.Init threw exception. System.Exception: error:System.Boolean Neo.Compiler.MSIL.TestClasses.Contract_NULL::StorageAndConvertToBigInteger(System.String)::IL_0024 Call System.Boolean System.Nullable`1<System.Numerics.BigInteger>::get_HasValue() ---> System.Exception: unknown call: System.Boolean System.Nullable`1<System.Numerics.BigInteger>::get_HasValue()
       in: System.Boolean Neo.Compiler.MSIL.TestClasses.Contract_NULL::StorageAndConvertToBigInteger(System.String)
    .
  堆栈跟踪: 
    ModuleConverter._ConvertCall(OpCode src, NeoMethod to) 行 742
    ModuleConverter.ConvertCode(ILMethod method, OpCode src, NeoMethod to) 行 888
    ModuleConverter.FillMethod(ILMethod from, NeoMethod to, Boolean withReturn) 行 434

It's problably we have not handle the System.Boolean System.Nullable1<System.Numerics.BigInteger>::get_HasValue()`

But if we rewrite the code as following, it will be compiled successful.

public static bool CheckNullConvertToBigInteger(string code)
{
       var m = Storage.Get(code);
       var k = m?.AsBigInteger()??0;  
       return k == null;
}

Another case

public static bool CheckStorageIsNotNull(string operation, object[] args)
{
        var m = Storage.Get(code); // if code isn't exist in storage
       return m != null;  // <---- The vm will execute failed, as this code will be parsed to OpCode.GT 
 }

image

How to solve it?

One way is to add null support in vm Opcode.GT.

Another is to add a check in compiler, and convert to OpCode.NOTEQUAL or OpCode.ISNULL, which must recognize the null parameters.

This is closed by #183

Include contract metadata in .abi.json file (master-2.x branch)

I propose including contract deployment information in the .abi.json file generated by NEON compiler. NEON could retrieve this information from assembly attributes specified in the C# source code (and provide reasonable defaults if the values are not specified).

By declaring this information in source, we reduce the information needed at deployment time, making it easier to automate deployment via neo-express and/or visual devtracker

NEON would generate contract metadata as follows:

There should not be separate versions of NEON for NEO 2 and 3

having separate versions of NEON targeting NEO 2's VM and NEO 3's VM is going to be difficult for developers to manage. Instead of separate binaries, there should be a command-line switch specifying which VM version the developer is targeting.

As a suggestion, we could follow the model the C# compiler uses for specifying versions. The langversion command-line switch allows users to specify an exact version like "7.3" or versions that can change between releases such as "Latest".

Neo 2 devpack not passing tests

How to reproduce:

  • Clone neo-devpack-dotnet
  • Checkout master-2.x
  • Open the solution
  • Run MSIL Unit tests

Result:
image

I managed to fix some tests (the problem was the dll name was misconfigured), but now I have a much bigger concern: the code is actually broken.
This works:

public static string UnitTest_003()
{
       return "Unit Test";
}

But this doesn't:

public static byte UnitTest_001()
{
     var nb = new byte[] { 1, 2, 3, 4 };
     return nb[2];
}

@devhawk

Add support to 'long' switch statements

There is a problem with the switch instruction, it seems that works if we have less entries than 6, with more, it doesn't works.

I made a pull request for test this issue at, #87

if you comment some entries, the test will work

Missing XML comments for Neo.SmartContract.Framework project

While using the nuget package I noticed there were no xml comments whatsoever, but in NEO's website all the API is documented.
It would be nice to have the website docs translated in the XML comments.

Also, are there plans for multilanguage comments?

gen abi error compiling example smart contracts

Compiling EventExample, ICO_Template or NEP5 contracts from https://github.com/neo-project/examples/csharp with neon compiler from the master branch of this repo fails with a gen abi error.

Example Output:

PS> dotnet build                                                                                                                                                                                                                                                                Microsoft (R) Build Engine version 16.2.32702+c4012a063 for .NET Core                                                                                                                                                                                                           Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 114.11 ms for C:\Users\harry\Source\neo\official\examples\csharp\ICO_Template\ICO_Template.csproj.
  ICO_Template -> C:\Users\harry\Source\neo\official\examples\csharp\ICO_Template\bin\Debug\net46\ICO_Template.dll
  Neo.Compiler.MSIL console app v2.4.1.0
  Find entrypoint:System.Object Neo.SmartContract.ICO_Template::Main(System.String,System.Object[])
  convert succ
EXEC : gen abi error : System.NullReferenceException: Object reference not set to an instance of an object. [C:\Users\harry\Source\neo\official\examples\csharp\ICO_Template\ICO_Template.csproj]
     at vmtool.FuncExport.ConvType(String _type) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\FuncExport.cs:line 60
     at vmtool.FuncExport.Export(NeoModule module, Byte[] script) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\FuncExport.cs:line 166
     at Neo.Compiler.Program.Main(String[] args) in C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\Program.cs:line 94
  write:ICO_Template.avm
  write:ICO_Template.abi.json
  SUCC
C:\Users\harry\Source\neo\official\examples\csharp\Directory.Build.targets(4,5): error MSB3073: The command "dotnet C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\bin\Debug\netcoreapp2.0\neon.dll ICO_Template.dll" exited with code -1. [C:\Users\harry\Source\neo\official\examples\csharp\ICO_Template\ICO_Template.csproj]

Build FAILED.

EXEC : gen abi error : System.NullReferenceException: Object reference not set to an instance of an object. [C:\Users\harry\Source\neo\official\examples\csharp\ICO_Template\ICO_Template.csproj]                                                                               C:\Users\harry\Source\neo\official\examples\csharp\Directory.Build.targets(4,5): error MSB3073: The command "dotnet C:\Users\harry\Source\neo\official\devpack-dotnet_master-3.x\src\Neo.Compiler.MSIL\bin\Debug\netcoreapp2.0\neon.dll ICO_Template.dll" exited with code -1. [C:\Users\harry\Source\neo\official\examples\csharp\ICO_Template\ICO_Template.csproj]
    0 Warning(s)                                                                                                                                                                                                                                                                    2 Error(s)

Time Elapsed 00:00:01.41

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.