neo-project / neo-devpack-dotnet Goto Github PK
View Code? Open in Web Editor NEWNEO Development Pack
License: MIT License
NEO Development Pack
License: MIT License
Master branch has added FeatureAttribute
while master-2.x has ContractHasStorage/ContractHasDynamicInvoke/ContractIsPayable. Need to change master-2.x to match master branch
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(); }
The C# template has been changed, but the VB template has not.
For developers we have two steps in order to compile from a c# code.
I want to allow neon to do all in one step.
Proposed solution: #131
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
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
#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
This is syntax sugar.with support of hashtable seems much convenience to save/read in smartcontract.
I think use hashTable to save/read is much convenience , this can reduce the complexity of contract development and easier to understand
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;
}
na
na
na
na
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?
Problem
Local out of memory abusing large arrays
Also, the constructor's detection need to be improved because is bypaseable using cctor
as class name
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];
}
}
}
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)
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?
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
2.rpc getnep5balances, gas balance didn't change, gas balance = 10
3.make a transfer
transaction, list asset, gas balance = 6.9723922
4.rpc getnep5balances, gas balance changed, gas balance = 6.9723922
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"
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
NEP-5
From Native NEP-5
From Neo-cli
Note: This is not an 'ICO' template, only NEP-5 (for now)
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.
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 []
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 ?
Implement fixes and changes to enable cross platform compatibility with Visual Studio for Mac.
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.
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
We should use the same folder structure as neo-vm
.
src/
test/
templates/
It is easy to configure travis with this configuration, and is more organized
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
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:
Neo.compiler.MSIL -> dll
Neo.compiler.MSIL.CIL -> exe
what do you think?
Port #86 to master-2.x branch
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
current version of Neo.Compiler.MSIL is v2.4.1.1. I recommend moving to v2.6.
Since neo-project/neo#163 is done, we should add these method calls to the next version of c# devpack.
Hi,
For a better experience, I think our Storage.Put(key, value) should automatically call .Serialize() if we send an object.
At least the version I have here, it only accepts byte[], meaning we have to call Serialize manually.
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:"
}
The first version of this code is available in the neon-de fork but that format needs to be improved and the code needs to be moved over to the official neon compiler
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
NEOVM had some change:
1.redesign opcodes
2.delete altstack and add some slot.
I am working on it.
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.
I also invoke static method and got correct return value. However when I invoke deploy
method, it returned fault straightly.
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;
}
}
}
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.Nullable
1<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;
}
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
}
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
We should remove these conditional compilations.
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:
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".
As per NEP-3, in smart contracts do not have return types. NEON should fail to compile contracts that have event delegates with return values
How to reproduce:
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];
}
we had a asm
https://github.com/neo-project/neo-compiler/tree/master/neoa,but that project had be closed.
maybe create a project repository "neo-devpack-asm".
and I want to create a middle layer for compilers,like llvm.
maybe can create a project repository "neolinker",
all compilers just need to compiler code to a middle format,then call neolinker to get .avm
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
This is the 3.x version of #149. FYI, this work will start in the Neo3 preview timeframe
It's added to neo-project
but not yet in the smart contract framework so can't use it.
neo-project/neo@a234978f2
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?
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.