From 6051662f57b3484d8859db319b550a537a9158ea Mon Sep 17 00:00:00 2001 From: Harry Pierson Date: Mon, 9 Nov 2020 22:11:58 -0800 Subject: [PATCH] Add UInt160, UInt256 and ECPoint to SmartContract Framework (#362) --- src/Neo.Compiler.MSIL/Compiler.cs | 5 +- src/Neo.Compiler.MSIL/FuncExport.cs | 8 ++- src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs | 55 +++++++++-------- src/Neo.Compiler.MSIL/MSIL/Converter.cs | 4 +- .../Neo.Compiler.MSIL.csproj | 10 +++- .../ContractHashAttribute.cs | 10 ++++ src/Neo.SmartContract.Framework/ECPoint.cs | 28 +++++++++ src/Neo.SmartContract.Framework/Helper.cs | 2 +- .../Services/Neo/Account.cs | 2 +- .../Services/Neo/Block.cs | 8 +-- .../Services/Neo/Blockchain.cs | 10 ++-- .../Services/Neo/Contract.cs | 6 +- .../Services/Neo/Crypto.cs | 8 +-- .../Services/Neo/Designation.cs | 3 +- .../Services/Neo/GAS.cs | 5 +- .../Services/Neo/NEO.cs | 20 ++++--- .../Services/Neo/Notification.cs | 2 +- .../Services/Neo/Oracle.cs | 1 + .../Services/Neo/Policy.cs | 7 ++- .../Services/Neo/Runtime.cs | 7 ++- .../Services/Neo/Transaction.cs | 4 +- .../Services/System/Callback.cs | 2 +- .../Services/System/ExecutionEngine.cs | 6 +- src/Neo.SmartContract.Framework/UInt160.cs | 37 ++++++++++++ src/Neo.SmartContract.Framework/UInt256.cs | 37 ++++++++++++ .../Template.NEP5.CSharp/NEP5.Crowdsale.cs | 6 +- .../Template.NEP5.CSharp/NEP5.Helpers.cs | 6 +- .../Template.NEP5.CSharp/NEP5.Methods.cs | 9 +-- templates/Template.NEP5.CSharp/NEP5.cs | 7 +-- .../Storage/AssetStorage.cs | 11 ++-- .../Neo.Compiler.MSIL.UnitTests.csproj | 4 +- .../TestClasses/Contract_NativeContracts.cs | 7 ++- .../TestClasses/Contract_OptimizationTest.cs | 2 +- .../TestClasses/Contract_StaticVarInit.cs | 2 +- .../TestClasses/Contract_UIntTypes.cs | 13 ++++ .../UnitTest_NativeContracts.cs | 16 ++++- .../UnitTest_StaticVar.cs | 7 ++- .../UnitTest_Types.cs | 59 +++++++++++++++++++ .../FeatureTest.cs | 3 + ...o.SmartContract.Framework.UnitTests.csproj | 3 + .../OpcodeTest.cs | 4 +- .../Services/Neo/StaticStorageMapTest.cs | 3 + .../Services/Neo/StorageTest.cs | 3 + .../Services/System/CallbackTest.cs | 4 +- .../Services/System/ExecutionEngineTest.cs | 4 +- .../StackItemTypeTest.cs | 7 ++- .../SyscallCallbackTest.cs | 4 +- .../SyscallTest.cs | 6 +- .../TestClasses/Contract_Account.cs | 2 +- .../TestClasses/Contract_Blockchain.cs | 10 ++-- .../TestClasses/Contract_Callback.cs | 4 +- .../TestClasses/Contract_Contract.cs | 4 +- .../TestClasses/Contract_Crypto.cs | 17 +++--- .../TestClasses/Contract_ExecutionEngine.cs | 6 +- .../TestClasses/Contract_Helper.cs | 4 +- .../TestClasses/Contract_Native.cs | 13 ++-- .../TestClasses/Contract_Runtime.cs | 19 ++---- .../Contract_SupportedStandards.cs | 2 +- .../TestClasses/Contract_UInt.cs | 15 +++++ .../UIntTest.cs | 38 ++++++++++++ 60 files changed, 459 insertions(+), 152 deletions(-) create mode 100644 src/Neo.SmartContract.Framework/ContractHashAttribute.cs create mode 100644 src/Neo.SmartContract.Framework/ECPoint.cs create mode 100644 src/Neo.SmartContract.Framework/UInt160.cs create mode 100644 src/Neo.SmartContract.Framework/UInt256.cs create mode 100644 tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_UIntTypes.cs create mode 100644 tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_UInt.cs create mode 100644 tests/Neo.SmartContract.Framework.UnitTests/UIntTest.cs diff --git a/src/Neo.Compiler.MSIL/Compiler.cs b/src/Neo.Compiler.MSIL/Compiler.cs index 0fa61a753..b585a74c0 100644 --- a/src/Neo.Compiler.MSIL/Compiler.cs +++ b/src/Neo.Compiler.MSIL/Compiler.cs @@ -1,3 +1,5 @@ +extern alias scfx; + using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.VisualBasic; @@ -7,6 +9,7 @@ using System.Linq; using System.Xml; using System.Xml.Linq; +using scfxSmartContract = scfx.Neo.SmartContract.Framework.SmartContract; namespace Neo.Compiler { @@ -200,7 +203,7 @@ private static MetadataReference[] CreateReferences(params string[] references) MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Runtime.Numerics.dll")), MetadataReference.CreateFromFile(typeof(System.ComponentModel.DisplayNameAttribute).Assembly.Location), MetadataReference.CreateFromFile(typeof(object).Assembly.Location), - MetadataReference.CreateFromFile(typeof(SmartContract.Framework.SmartContract).Assembly.Location), + MetadataReference.CreateFromFile(typeof(scfxSmartContract).Assembly.Location), }); refs.AddRange(references.Where(u => u != "Neo.SmartContract.Framework.dll").Select(u => MetadataReference.CreateFromFile(u))); return refs.ToArray(); diff --git a/src/Neo.Compiler.MSIL/FuncExport.cs b/src/Neo.Compiler.MSIL/FuncExport.cs index d9bf4033e..e91bf3e3b 100644 --- a/src/Neo.Compiler.MSIL/FuncExport.cs +++ b/src/Neo.Compiler.MSIL/FuncExport.cs @@ -1,10 +1,13 @@ +extern alias scfx; + using Mono.Cecil; using Neo.IO.Json; -using Neo.SmartContract.Framework; using System; using System.Collections.Generic; using System.Linq; using System.Text; +using IApiInterface = scfx.Neo.SmartContract.Framework.IApiInterface; +using ContractFeatures = scfx.Neo.SmartContract.Framework.ContractFeatures; namespace Neo.Compiler { @@ -47,6 +50,9 @@ internal static string ConvType(TypeReference t) case "IInteropInterface": return "InteropInterface"; case "System.Void": return "Void"; case "System.Object": return "Any"; + case "Neo.UInt160": return "Hash160"; + case "Neo.UInt256": return "Hash256"; + case "Neo.Cryptography.ECC.ECPoint": return "PublicKey"; } if (t.IsArray) return "Array"; diff --git a/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs b/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs index c5383905c..9241258f3 100644 --- a/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs +++ b/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs @@ -1,4 +1,5 @@ using Mono.Cecil; +using Neo.IO; using Neo.SmartContract; using System; using System.Collections.Generic; @@ -164,7 +165,7 @@ public bool IsSysCall(Mono.Cecil.MethodDefinition defs, out string name) } */ - public bool IsContractCall(Mono.Cecil.MethodDefinition defs, out byte[] hash) + public bool IsContractCall(Mono.Cecil.MethodDefinition defs, out UInt160 hash) { if (defs == null) { @@ -181,19 +182,12 @@ public bool IsContractCall(Mono.Cecil.MethodDefinition defs, out byte[] hash) if (a.Type.FullName == "System.String") { string hashstr = (string)a.Value; - - try + if (UInt160.TryParse(hashstr, out hash)) { - hash = hashstr.HexString2Bytes(); - if (hash.Length != 20) throw new Exception("Wrong hash:" + hashstr); - - hash = hash.Reverse().ToArray(); return true; } - catch - { - throw new Exception("hex format error:" + hashstr); - } + + throw new Exception("hex format error:" + hashstr); } else { @@ -202,12 +196,12 @@ public bool IsContractCall(Mono.Cecil.MethodDefinition defs, out byte[] hash) { throw new Exception("hash too short."); } - hash = new byte[20]; + var buffer = new byte[20]; for (var i = 0; i < 20; i++) { - hash[i] = (byte)list[i].Value; + buffer[i] = (byte)list[i].Value; } - hash = hash.Reverse().ToArray(); + hash = new UInt160(buffer); return true; } } @@ -401,7 +395,7 @@ private int ConvertCall(OpCode src, NeoMethod to) int calltype = 0; string callname; int callpcount = 0; - byte[] callhash = null; + UInt160 callhash = null; VM.OpCode[] callcodes = null; string[] calldata = null; @@ -874,20 +868,28 @@ private int ConvertCall(OpCode src, NeoMethod to) } else if (calltype == 4) { - // Package the arguments into an array. - ConvertPushNumber(pcount, null, to); - Convert1by1(VM.OpCode.PACK, null, to); + if (defs.IsGetter + && defs.CustomAttributes.Any(a => a.AttributeType.FullName == "Neo.SmartContract.Framework.ContractHashAttribute")) + { + ConvertPushDataArray(callhash.ToArray(), src, to); + } + else + { + // Package the arguments into an array. + ConvertPushNumber(pcount, null, to); + Convert1by1(VM.OpCode.PACK, null, to); - // Push call method name, the first letter should be lowercase. - ConvertPushString(GetMethodName(defs.Body.Method), src, to); + // Push call method name, the first letter should be lowercase. + ConvertPushString(GetMethodName(defs.Body.Method), src, to); - // Push contract hash. - ConvertPushDataArray(callhash, src, to); - Insert1(VM.OpCode.SYSCALL, "", to, BitConverter.GetBytes(ApplicationEngine.System_Contract_Call)); + // Push contract hash. + ConvertPushDataArray(callhash.ToArray(), src, to); + Insert1(VM.OpCode.SYSCALL, "", to, BitConverter.GetBytes(ApplicationEngine.System_Contract_Call)); - // If the return type is void, insert a DROP. - if (defs.ReturnType.FullName is "System.Void") - Insert1(VM.OpCode.DROP, "", to); + // If the return type is void, insert a DROP. + if (defs.ReturnType.FullName is "System.Void") + Insert1(VM.OpCode.DROP, "", to); + } } else if (calltype == 5) { @@ -1451,6 +1453,7 @@ private int ConvertInitObj(OpCode src, NeoMethod to) private int ConvertNewObj(ILMethod from, OpCode src, NeoMethod to) { var _type = (src.tokenUnknown as Mono.Cecil.MethodReference); + if (_type.FullName == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])") { return 0; // donothing; diff --git a/src/Neo.Compiler.MSIL/MSIL/Converter.cs b/src/Neo.Compiler.MSIL/MSIL/Converter.cs index dff61484f..fd941cb54 100644 --- a/src/Neo.Compiler.MSIL/MSIL/Converter.cs +++ b/src/Neo.Compiler.MSIL/MSIL/Converter.cs @@ -109,11 +109,11 @@ public NeoModule Convert(ILModule _in, ConvOption option = null) nm.paramtypes.Add(new NeoParam(src.name, src.type)); } - if (IsContractCall(m.Value.method, out byte[] outcall)) + if (IsContractCall(m.Value.method, out _)) continue; if (IsNonCall(m.Value.method)) continue; - if (IsMixAttribute(m.Value.method, out VM.OpCode[] opcodes, out string[] opdata)) + if (IsMixAttribute(m.Value.method, out _, out _)) continue; if (m.Key.Contains("::Main(")) diff --git a/src/Neo.Compiler.MSIL/Neo.Compiler.MSIL.csproj b/src/Neo.Compiler.MSIL/Neo.Compiler.MSIL.csproj index 257c9abe1..cef95326c 100644 --- a/src/Neo.Compiler.MSIL/Neo.Compiler.MSIL.csproj +++ b/src/Neo.Compiler.MSIL/Neo.Compiler.MSIL.csproj @@ -46,6 +46,14 @@ - + + + scfx + diff --git a/src/Neo.SmartContract.Framework/ContractHashAttribute.cs b/src/Neo.SmartContract.Framework/ContractHashAttribute.cs new file mode 100644 index 000000000..9995ec41d --- /dev/null +++ b/src/Neo.SmartContract.Framework/ContractHashAttribute.cs @@ -0,0 +1,10 @@ +using System; + +namespace Neo.SmartContract.Framework +{ + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + internal class ContractHashAttribute : Attribute + { + + } +} diff --git a/src/Neo.SmartContract.Framework/ECPoint.cs b/src/Neo.SmartContract.Framework/ECPoint.cs new file mode 100644 index 000000000..360d10807 --- /dev/null +++ b/src/Neo.SmartContract.Framework/ECPoint.cs @@ -0,0 +1,28 @@ +using Neo.SmartContract.Framework; + +namespace Neo.Cryptography.ECC +{ + public class ECPoint + { + [OpCode(OpCode.CONVERT, StackItemType.ByteString)] + [OpCode(OpCode.DUP)] + [OpCode(OpCode.SIZE)] + [OpCode(OpCode.PUSHINT8, "21")] // 0x21 == 33 bytes expected array size + [OpCode(OpCode.NUMEQUAL)] + [OpCode(OpCode.ASSERT)] + public static extern explicit operator ECPoint(byte[] value); + + [OpCode(OpCode.DUP)] + [OpCode(OpCode.SIZE)] + [OpCode(OpCode.PUSHINT8, "21")] // 0x21 == 33 bytes expected array size + [OpCode(OpCode.NUMEQUAL)] + [OpCode(OpCode.ASSERT)] + public static extern explicit operator ECPoint(ByteString value); + + [OpCode(OpCode.CONVERT, StackItemType.Buffer)] + public static extern explicit operator byte[](ECPoint value); + + [Script] + public static extern implicit operator ByteString(ECPoint value); + } +} diff --git a/src/Neo.SmartContract.Framework/Helper.cs b/src/Neo.SmartContract.Framework/Helper.cs index 1ae1ed83f..150b66486 100644 --- a/src/Neo.SmartContract.Framework/Helper.cs +++ b/src/Neo.SmartContract.Framework/Helper.cs @@ -193,7 +193,7 @@ public static byte ToByte(this int source) /// Example: "AFsCjUGzicZmXQtWpwVt6hNeJTBwSipJMS".ToScriptHash() generates 0102030405060708090a0b0c0d0e0faabbccddee /// [NonemitWithConvert(ConvertMethod.ToScriptHash)] - public extern static byte[] ToScriptHash(this string address); + public extern static UInt160 ToScriptHash(this string address); [NonemitWithConvert(ConvertMethod.ToBigInteger)] public extern static BigInteger ToBigInteger(this string text); diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Account.cs b/src/Neo.SmartContract.Framework/Services/Neo/Account.cs index 28c1f892d..484233cd9 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Account.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Account.cs @@ -3,6 +3,6 @@ namespace Neo.SmartContract.Framework.Services.Neo public class Account { [Syscall("System.Contract.IsStandard")] - public static extern bool IsStandard(byte[] scripthash); + public static extern bool IsStandard(UInt160 scripthash); } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Block.cs b/src/Neo.SmartContract.Framework/Services/Neo/Block.cs index bfeefd873..9ce1be81a 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Block.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Block.cs @@ -2,13 +2,13 @@ namespace Neo.SmartContract.Framework.Services.Neo { public class Block { - public readonly byte[] Hash; + public readonly UInt256 Hash; public readonly uint Version; - public readonly byte[] PrevHash; - public readonly byte[] MerkleRoot; + public readonly UInt256 PrevHash; + public readonly UInt256 MerkleRoot; public readonly ulong Timestamp; public readonly uint Index; - public readonly byte[] NextConsensus; + public readonly UInt160 NextConsensus; public readonly int TransactionsCount; } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Blockchain.cs b/src/Neo.SmartContract.Framework/Services/Neo/Blockchain.cs index 05218acc0..d23580261 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Blockchain.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Blockchain.cs @@ -11,21 +11,21 @@ public static class Blockchain public static extern Block GetBlock(uint height); [Syscall("System.Blockchain.GetBlock")] - public static extern Block GetBlock(byte[] hash); + public static extern Block GetBlock(UInt256 hash); [Syscall("System.Blockchain.GetTransaction")] - public static extern Transaction GetTransaction(byte[] hash); + public static extern Transaction GetTransaction(UInt256 hash); [Syscall("System.Blockchain.GetTransactionFromBlock")] - public static extern Transaction GetTransactionFromBlock(byte[] blockHash, int txIndex); + public static extern Transaction GetTransactionFromBlock(UInt256 blockHash, int txIndex); [Syscall("System.Blockchain.GetTransactionFromBlock")] public static extern Transaction GetTransactionFromBlock(uint blockIndex, int txIndex); [Syscall("System.Blockchain.GetTransactionHeight")] - public static extern BigInteger GetTransactionHeight(byte[] hash); + public static extern BigInteger GetTransactionHeight(UInt256 hash); [Syscall("System.Blockchain.GetContract")] - public static extern Contract GetContract(byte[] script_hash); + public static extern Contract GetContract(UInt160 script_hash); } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Contract.cs b/src/Neo.SmartContract.Framework/Services/Neo/Contract.cs index e5ee44652..8b52e29a9 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Contract.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Contract.cs @@ -23,10 +23,10 @@ public class Contract public readonly bool IsPayable; [Syscall("System.Contract.Call")] - public static extern object Call(byte[] scriptHash, string method, object[] arguments); + public static extern object Call(UInt160 scriptHash, string method, object[] arguments); [Syscall("System.Contract.CallEx")] - public static extern object CallEx(byte[] scriptHash, string method, object[] arguments, CallFlags flag); + public static extern object CallEx(UInt160 scriptHash, string method, object[] arguments, CallFlags flag); [Syscall("System.Contract.Create")] public static extern Contract Create(byte[] script, string manifest); @@ -41,6 +41,6 @@ public class Contract public static extern byte GetCallFlags(); [Syscall("System.Contract.CreateStandardAccount")] - public static extern byte[] CreateStandardAccount(byte[] pubKey); + public static extern UInt160 CreateStandardAccount(Cryptography.ECC.ECPoint pubKey); } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Crypto.cs b/src/Neo.SmartContract.Framework/Services/Neo/Crypto.cs index d725884bf..88edb7441 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Crypto.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Crypto.cs @@ -21,19 +21,19 @@ public static class ECDsa public static class Secp256r1 { [Syscall("Neo.Crypto.VerifyWithECDsaSecp256r1")] - public extern static bool Verify(byte[] message, byte[] pubkey, byte[] signature); + public extern static bool Verify(byte[] message, Cryptography.ECC.ECPoint pubkey, byte[] signature); [Syscall("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")] - public extern static bool CheckMultiSig(byte[] message, byte[][] pubkey, byte[][] signature); + public extern static bool CheckMultiSig(byte[] message, Cryptography.ECC.ECPoint[] pubkey, byte[][] signature); } public static class Secp256k1 { [Syscall("Neo.Crypto.VerifyWithECDsaSecp256k1")] - public extern static bool Verify(byte[] message, byte[] pubkey, byte[] signature); + public extern static bool Verify(byte[] message, Cryptography.ECC.ECPoint pubkey, byte[] signature); [Syscall("Neo.Crypto.CheckMultisigWithECDsaSecp256k1")] - public extern static bool CheckMultiSig(byte[] message, byte[][] pubkey, byte[][] signature); + public extern static bool CheckMultiSig(byte[] message, Cryptography.ECC.ECPoint[] pubkey, byte[][] signature); } } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Designation.cs b/src/Neo.SmartContract.Framework/Services/Neo/Designation.cs index ca60d08ae..c0b831b81 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Designation.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Designation.cs @@ -5,7 +5,8 @@ namespace Neo.SmartContract.Framework.Services.Neo [Contract("0x763afecf3ebba0a67568a2c8be06e8f068c62666")] public class Designation { + public static extern UInt160 Hash { [ContractHash] get; } public static extern string Name { get; } - public static extern byte[][] GetDesignatedByRole(DesignationRole role); + public static extern Cryptography.ECC.ECPoint[] GetDesignatedByRole(DesignationRole role); } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/GAS.cs b/src/Neo.SmartContract.Framework/Services/Neo/GAS.cs index f6ed8ea9c..55840d805 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/GAS.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/GAS.cs @@ -7,11 +7,12 @@ namespace Neo.SmartContract.Framework.Services.Neo [Contract("0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc")] public class GAS { + public static extern UInt160 Hash { [ContractHash] get; } public static extern string Name { get; } public static extern string Symbol { get; } public static extern byte Decimals { get; } public static extern BigInteger TotalSupply(); - public static extern BigInteger BalanceOf(byte[] account); - public static extern bool Transfer(byte[] from, byte[] to, BigInteger amount); + public static extern BigInteger BalanceOf(UInt160 account); + public static extern bool Transfer(UInt160 from, UInt160 to, BigInteger amount); } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/NEO.cs b/src/Neo.SmartContract.Framework/Services/Neo/NEO.cs index 664c7184b..8910a003f 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/NEO.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/NEO.cs @@ -1,28 +1,30 @@ #pragma warning disable CS0626 using System.Numerics; +using Neo.Cryptography.ECC; namespace Neo.SmartContract.Framework.Services.Neo { [Contract("0xde5f57d430d3dece511cf975a8d37848cb9e0525")] public class NEO { + public static extern UInt160 Hash { [ContractHash] get; } public static extern string Name { get; } public static extern string Symbol { get; } public static extern byte Decimals { get; } public static extern BigInteger TotalSupply(); - public static extern BigInteger BalanceOf(byte[] account); - public static extern bool Transfer(byte[] from, byte[] to, BigInteger amount); + public static extern BigInteger BalanceOf(UInt160 account); + public static extern bool Transfer(UInt160 from, UInt160 to, BigInteger amount); public static extern bool SetGasPerBlock(BigInteger gasPerBlock); public static extern BigInteger GetGasPerBlock(); - public static extern BigInteger UnclaimedGas(byte[] account, uint end); + public static extern BigInteger UnclaimedGas(UInt160 account, uint end); - public static extern bool RegisterCandidate(byte[] pubkey); - public static extern bool UnRegisterCandidate(byte[] pubkey); - public static extern bool Vote(byte[] account, byte[] voteTo); - public static extern (string, BigInteger)[] GetCandidates(); - public static extern string[] GetCommittee(); - public static extern string[] GetNextBlockValidators(); + public static extern bool RegisterCandidate(ECPoint pubkey); + public static extern bool UnRegisterCandidate(ECPoint pubkey); + public static extern bool Vote(UInt160 account, ECPoint voteTo); + public static extern (ECPoint, BigInteger)[] GetCandidates(); + public static extern ECPoint[] GetCommittee(); + public static extern ECPoint[] GetNextBlockValidators(); } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Notification.cs b/src/Neo.SmartContract.Framework/Services/Neo/Notification.cs index 498ad6ad3..3385032de 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Notification.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Notification.cs @@ -5,7 +5,7 @@ public class Notification : IApiInterface /// /// Sender script hash /// - public readonly byte[] ScriptHash; + public readonly UInt160 ScriptHash; /// /// Notification's name diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Oracle.cs b/src/Neo.SmartContract.Framework/Services/Neo/Oracle.cs index c7fdb028c..f1e376bbc 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Oracle.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Oracle.cs @@ -5,6 +5,7 @@ namespace Neo.SmartContract.Framework.Services.Neo [Contract("0x3c05b488bf4cf699d0631bf80190896ebbf38c3b")] public class Oracle { + public static extern UInt160 Hash { [ContractHash] get; } public const uint MinimumResponseFee = 0_10000000; public static extern string Name { get; } public static extern void Request(string url, string filter, string callback, object userData, long gasForResponse); diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Policy.cs b/src/Neo.SmartContract.Framework/Services/Neo/Policy.cs index ce70e65be..d68b43c3d 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Policy.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Policy.cs @@ -8,17 +8,18 @@ namespace Neo.SmartContract.Framework.Services.Neo [Contract("0xce06595079cd69583126dbfd1d2e25cca74cffe9")] public class Policy { + public static extern UInt160 Hash { [ContractHash] get; } public static extern string Name(); public static extern uint GetMaxTransactionsPerBlock(); public static extern uint GetMaxBlockSize(); public static extern long GetMaxBlockSystemFee(); public static extern BigInteger GetFeePerByte(); - public static extern string[] IsBlocked(byte[] account); + public static extern string[] IsBlocked(UInt160 account); public static extern bool SetMaxBlockSize(uint value); public static extern bool SetMaxTransactionsPerBlock(uint value); public static extern bool SetMaxBlockSystemFee(long value); public static extern bool SetFeePerByte(long value); - public static extern bool BlockAccount(byte[] account); - public static extern bool UnblockAccount(byte[] account); + public static extern bool BlockAccount(UInt160 account); + public static extern bool UnblockAccount(UInt160 account); } } diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Runtime.cs b/src/Neo.SmartContract.Framework/Services/Neo/Runtime.cs index 4d124c44e..ba74cd494 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Runtime.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Runtime.cs @@ -40,10 +40,13 @@ public static extern long GasLeft /// The stackitem 'State' can be of any kind (a number, a string, an array, ...), so it's up to the developer perform the expected cast here /// [Syscall("System.Runtime.GetNotifications")] - public static extern Notification[] GetNotifications(byte[] hash = null); + public static extern Notification[] GetNotifications(UInt160 hash = null); [Syscall("System.Runtime.CheckWitness")] - public static extern bool CheckWitness(byte[] hashOrPubkey); + public static extern bool CheckWitness(UInt160 hash); + + [Syscall("System.Runtime.CheckWitness")] + public static extern bool CheckWitness(Cryptography.ECC.ECPoint pubkey); [Syscall("System.Runtime.Log")] public static extern void Log(string message); diff --git a/src/Neo.SmartContract.Framework/Services/Neo/Transaction.cs b/src/Neo.SmartContract.Framework/Services/Neo/Transaction.cs index 7bde5847f..602cf0a92 100644 --- a/src/Neo.SmartContract.Framework/Services/Neo/Transaction.cs +++ b/src/Neo.SmartContract.Framework/Services/Neo/Transaction.cs @@ -2,10 +2,10 @@ namespace Neo.SmartContract.Framework.Services.Neo { public class Transaction { - public readonly byte[] Hash; + public readonly UInt256 Hash; public readonly byte Version; public readonly uint Nonce; - public readonly byte[] Sender; + public readonly UInt160 Sender; public readonly long SystemFee; public readonly long NetworkFee; public readonly uint ValidUntilBlock; diff --git a/src/Neo.SmartContract.Framework/Services/System/Callback.cs b/src/Neo.SmartContract.Framework/Services/System/Callback.cs index 0e4ee18a4..4201a2093 100644 --- a/src/Neo.SmartContract.Framework/Services/System/Callback.cs +++ b/src/Neo.SmartContract.Framework/Services/System/Callback.cs @@ -95,7 +95,7 @@ public class Callback public static extern Callback Create(Func func); [Syscall("System.Callback.CreateFromMethod")] - public static extern Callback CreateFromMethod(byte[] hash, string method); + public static extern Callback CreateFromMethod(UInt160 hash, string method); [Syscall("System.Callback.CreateFromSyscall")] public static extern Callback CreateFromSyscall(SyscallCallback method); diff --git a/src/Neo.SmartContract.Framework/Services/System/ExecutionEngine.cs b/src/Neo.SmartContract.Framework/Services/System/ExecutionEngine.cs index d9a668e8e..2bae50d4c 100644 --- a/src/Neo.SmartContract.Framework/Services/System/ExecutionEngine.cs +++ b/src/Neo.SmartContract.Framework/Services/System/ExecutionEngine.cs @@ -8,19 +8,19 @@ public static extern IScriptContainer ScriptContainer get; } - public static extern byte[] ExecutingScriptHash + public static extern UInt160 ExecutingScriptHash { [Syscall("System.Runtime.GetExecutingScriptHash")] get; } - public static extern byte[] CallingScriptHash + public static extern UInt160 CallingScriptHash { [Syscall("System.Runtime.GetCallingScriptHash")] get; } - public static extern byte[] EntryScriptHash + public static extern UInt160 EntryScriptHash { [Syscall("System.Runtime.GetEntryScriptHash")] get; diff --git a/src/Neo.SmartContract.Framework/UInt160.cs b/src/Neo.SmartContract.Framework/UInt160.cs new file mode 100644 index 000000000..9785b4cbe --- /dev/null +++ b/src/Neo.SmartContract.Framework/UInt160.cs @@ -0,0 +1,37 @@ +using Neo.SmartContract.Framework; + +namespace Neo +{ + public class UInt160 + { + public static extern UInt160 Zero { [OpCode(OpCode.PUSHDATA1, "140000000000000000000000000000000000000000")] get; } + + public extern bool IsZero + { + [OpCode(OpCode.PUSH0)] + [OpCode(OpCode.NUMEQUAL)] + get; + } + + [OpCode(OpCode.CONVERT, StackItemType.ByteString)] + [OpCode(OpCode.DUP)] + [OpCode(OpCode.SIZE)] + [OpCode(OpCode.PUSHINT8, "14")] // 0x14 == 20 bytes expected array size + [OpCode(OpCode.NUMEQUAL)] + [OpCode(OpCode.ASSERT)] + public static extern explicit operator UInt160(byte[] value); + + [OpCode(OpCode.DUP)] + [OpCode(OpCode.SIZE)] + [OpCode(OpCode.PUSHINT8, "14")] // 0x14 == 20 bytes expected array size + [OpCode(OpCode.NUMEQUAL)] + [OpCode(OpCode.ASSERT)] + public static extern explicit operator UInt160(ByteString value); + + [OpCode(OpCode.CONVERT, StackItemType.Buffer)] + public static extern explicit operator byte[](UInt160 value); + + [Script] + public static extern implicit operator ByteString(UInt160 value); + } +} diff --git a/src/Neo.SmartContract.Framework/UInt256.cs b/src/Neo.SmartContract.Framework/UInt256.cs new file mode 100644 index 000000000..126cfdff8 --- /dev/null +++ b/src/Neo.SmartContract.Framework/UInt256.cs @@ -0,0 +1,37 @@ +using Neo.SmartContract.Framework; + +namespace Neo +{ + public class UInt256 + { + public static extern UInt256 Zero { [OpCode(OpCode.PUSHDATA1, "200000000000000000000000000000000000000000000000000000000000000000")] get; } + + public extern bool IsZero + { + [OpCode(OpCode.PUSH0)] + [OpCode(OpCode.NUMEQUAL)] + get; + } + + [OpCode(OpCode.CONVERT, StackItemType.ByteString)] + [OpCode(OpCode.DUP)] + [OpCode(OpCode.SIZE)] + [OpCode(OpCode.PUSHINT8, "20")] // 0x20 == 32 bytes expected array size + [OpCode(OpCode.NUMEQUAL)] + [OpCode(OpCode.ASSERT)] + public static extern explicit operator UInt256(byte[] value); + + [OpCode(OpCode.DUP)] + [OpCode(OpCode.SIZE)] + [OpCode(OpCode.PUSHINT8, "20")] // 0x20 == 32 bytes expected array size + [OpCode(OpCode.NUMEQUAL)] + [OpCode(OpCode.ASSERT)] + public static extern explicit operator UInt256(ByteString value); + + [OpCode(OpCode.CONVERT, StackItemType.Buffer)] + public static extern explicit operator byte[](UInt256 value); + + [Script] + public static extern implicit operator ByteString(UInt256 value); + } +} diff --git a/templates/Template.NEP5.CSharp/NEP5.Crowdsale.cs b/templates/Template.NEP5.CSharp/NEP5.Crowdsale.cs index 0b8367bcf..e711be0f3 100644 --- a/templates/Template.NEP5.CSharp/NEP5.Crowdsale.cs +++ b/templates/Template.NEP5.CSharp/NEP5.Crowdsale.cs @@ -16,7 +16,7 @@ private static BigInteger GetTransactionAmount(Notification notification) // Checks notification format if (state.Length != 3) return 0; // Check dest - if ((byte[])state[1] != ExecutionEngine.ExecutingScriptHash) return 0; + if ((Neo.UInt160)state[1] != ExecutionEngine.ExecutingScriptHash) return 0; // Amount var amount = (BigInteger)state[2]; if (amount < 0) return 0; @@ -37,11 +37,11 @@ public static bool Mint() { var notification = notifications[i]; - if (notification.ScriptHash == NeoToken) + if (notification.ScriptHash == NEO.Hash) { neo += GetTransactionAmount(notification); } - else if (notification.ScriptHash == GasToken) + else if (notification.ScriptHash == GAS.Hash) { gas += GetTransactionAmount(notification); } diff --git a/templates/Template.NEP5.CSharp/NEP5.Helpers.cs b/templates/Template.NEP5.CSharp/NEP5.Helpers.cs index e1d141176..dcca14e7b 100644 --- a/templates/Template.NEP5.CSharp/NEP5.Helpers.cs +++ b/templates/Template.NEP5.CSharp/NEP5.Helpers.cs @@ -1,3 +1,4 @@ +using Neo; using Neo.SmartContract.Framework; using Neo.SmartContract.Framework.Services.Neo; @@ -5,8 +6,7 @@ namespace Template.NEP5.CSharp { public partial class NEP5 : SmartContract { - private static bool ValidateAddress(byte[] address) => address.Length == 20 && address.ToBigInteger() != 0; - - private static bool IsPayable(byte[] address) => Blockchain.GetContract(address)?.IsPayable ?? true; + private static bool ValidateAddress(UInt160 address) => !address.IsZero; + private static bool IsPayable(UInt160 address) => Blockchain.GetContract(address)?.IsPayable ?? true; } } diff --git a/templates/Template.NEP5.CSharp/NEP5.Methods.cs b/templates/Template.NEP5.CSharp/NEP5.Methods.cs index cf1e039f0..c37de6627 100644 --- a/templates/Template.NEP5.CSharp/NEP5.Methods.cs +++ b/templates/Template.NEP5.CSharp/NEP5.Methods.cs @@ -1,3 +1,4 @@ +using Neo; using Neo.SmartContract.Framework; using Neo.SmartContract.Framework.Services.Neo; using Neo.SmartContract.Framework.Services.System; @@ -10,15 +11,15 @@ public partial class NEP5 : SmartContract { public static BigInteger TotalSupply() => TotalSupplyStorage.Get(); - public static BigInteger BalanceOf(byte[] account) + public static BigInteger BalanceOf(UInt160 account) { - if (!ValidateAddress(account)) throw new Exception("The parameters account SHOULD be 20-byte addresses."); + if (!ValidateAddress(account)) throw new Exception("The parameters account SHOULD be a 20-byte non-zero address."); return AssetStorage.Get(account); } - public static bool Transfer(byte[] from, byte[] to, BigInteger amount) + public static bool Transfer(UInt160 from, UInt160 to, BigInteger amount) { - if (!ValidateAddress(from) || !ValidateAddress(to)) throw new Exception("The parameters from and to SHOULD be 20-byte addresses."); + if (!ValidateAddress(from) || !ValidateAddress(to)) throw new Exception("The parameters from and to SHOULD be 20-byte non-zero addresses."); if (amount <= 0) throw new Exception("The parameter amount MUST be greater than 0."); if (!IsPayable(to)) throw new Exception("Receiver cannot receive."); if (!Runtime.CheckWitness(from) && !from.Equals(ExecutionEngine.CallingScriptHash)) throw new Exception("No authorization."); diff --git a/templates/Template.NEP5.CSharp/NEP5.cs b/templates/Template.NEP5.CSharp/NEP5.cs index 107569dbd..9c2eb53dd 100644 --- a/templates/Template.NEP5.CSharp/NEP5.cs +++ b/templates/Template.NEP5.CSharp/NEP5.cs @@ -1,3 +1,4 @@ +using Neo; using Neo.SmartContract.Framework; using System; using System.ComponentModel; @@ -15,16 +16,14 @@ public partial class NEP5 : SmartContract #region Token Settings static readonly ulong MaxSupply = 10_000_000_000_000_000; static readonly ulong InitialSupply = 2_000_000_000_000_000; - static readonly byte[] Owner = "NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB".ToScriptHash(); + static readonly UInt160 Owner = "NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB".ToScriptHash(); static readonly ulong TokensPerNEO = 1_000_000_000; static readonly ulong TokensPerGAS = 1; - static readonly byte[] NeoToken = "0xde5f57d430d3dece511cf975a8d37848cb9e0525".HexToBytes(true); - static readonly byte[] GasToken = "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc".HexToBytes(true); #endregion #region Notifications [DisplayName("Transfer")] - public static event Action OnTransfer; + public static event Action OnTransfer; #endregion // When this contract address is included in the transaction signature, diff --git a/templates/Template.NEP5.CSharp/Storage/AssetStorage.cs b/templates/Template.NEP5.CSharp/Storage/AssetStorage.cs index 9e5de31d3..27294e3cf 100644 --- a/templates/Template.NEP5.CSharp/Storage/AssetStorage.cs +++ b/templates/Template.NEP5.CSharp/Storage/AssetStorage.cs @@ -1,3 +1,4 @@ +using Neo; using Neo.SmartContract.Framework; using Neo.SmartContract.Framework.Services.Neo; using System.Numerics; @@ -8,9 +9,9 @@ public static class AssetStorage { public static readonly string mapName = "asset"; - public static void Increase(byte[] key, BigInteger value) => Put(key, Get(key) + value); + public static void Increase(UInt160 key, BigInteger value) => Put(key, Get(key) + value); - public static void Reduce(byte[] key, BigInteger value) + public static void Reduce(UInt160 key, BigInteger value) { var oldValue = Get(key); if (oldValue == value) @@ -19,10 +20,10 @@ public static void Reduce(byte[] key, BigInteger value) Put(key, oldValue - value); } - public static void Put(byte[] key, BigInteger value) => Storage.CurrentContext.CreateMap(mapName).Put(key, value); + public static void Put(UInt160 key, BigInteger value) => Storage.CurrentContext.CreateMap(mapName).Put((byte[])key, value); - public static BigInteger Get(byte[] key) => Storage.CurrentContext.CreateMap(mapName).Get(key).ToBigInteger(); + public static BigInteger Get(UInt160 key) => Storage.CurrentContext.CreateMap(mapName).Get((byte[])key).ToBigInteger(); - public static void Remove(byte[] key) => Storage.CurrentContext.CreateMap(mapName).Delete(key); + public static void Remove(UInt160 key) => Storage.CurrentContext.CreateMap(mapName).Delete((byte[])key); } } diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Neo.Compiler.MSIL.UnitTests.csproj b/tests/Neo.Compiler.MSIL.UnitTests/Neo.Compiler.MSIL.UnitTests.csproj index 39bb6ae2c..3ba2fe80a 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/Neo.Compiler.MSIL.UnitTests.csproj +++ b/tests/Neo.Compiler.MSIL.UnitTests/Neo.Compiler.MSIL.UnitTests.csproj @@ -19,7 +19,9 @@ - + + scfx + diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_NativeContracts.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_NativeContracts.cs index 5523a90f2..b6b9d9d57 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_NativeContracts.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_NativeContracts.cs @@ -43,9 +43,14 @@ public static string GASSymbol() return GAS.Symbol; } - public static byte[][] getOracleNodes() + public static Cryptography.ECC.ECPoint[] getOracleNodes() { return Designation.GetDesignatedByRole(DesignationRole.Oracle); } + + public static UInt160 NEOHash() + { + return Neo.SmartContract.Framework.Services.Neo.NEO.Hash; + } } } diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_OptimizationTest.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_OptimizationTest.cs index 8d195d51f..2b25d95e0 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_OptimizationTest.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_OptimizationTest.cs @@ -5,7 +5,7 @@ namespace Neo.Compiler.MSIL.TestClasses { public class Contract_OptimizationTest : SmartContract.Framework.SmartContract { - private static byte[] Owner = "Ne9ipxm2sPUaetvh3ZvjhyCzRZqP355dTZ".ToScriptHash(); + private static Neo.UInt160 Owner = "Ne9ipxm2sPUaetvh3ZvjhyCzRZqP355dTZ".ToScriptHash(); public static bool Verify() { diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StaticVarInit.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StaticVarInit.cs index b21c02a5f..819c92f87 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StaticVarInit.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_StaticVarInit.cs @@ -5,7 +5,7 @@ namespace Neo.Compiler.MSIL.UnitTests.TestClasses class Contract_staticvar : SmartContract.Framework.SmartContract { //define and staticvar and initit with a runtime code. - static byte[] callscript = ExecutionEngine.EntryScriptHash; + static byte[] callscript = (byte[])ExecutionEngine.EntryScriptHash; public static object StaticInit() { diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_UIntTypes.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_UIntTypes.cs new file mode 100644 index 000000000..95386fe8e --- /dev/null +++ b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_UIntTypes.cs @@ -0,0 +1,13 @@ +namespace Neo.Compiler.MSIL.UnitTests.TestClasses +{ + class Contract_UIntTypes : SmartContract.Framework.SmartContract + { + static readonly UInt160 Owner = SmartContract.Framework.Helper.ToScriptHash("NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB"); + + public static bool checkOwner(UInt160 owner) { return owner == Owner; } + + public static bool checkZeroStatic(UInt160 owner) { return owner == UInt160.Zero; } + + public static UInt160 constructUInt160(byte[] bytes) { return (UInt160)bytes; } + } +} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NativeContracts.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NativeContracts.cs index 4c7751285..67ea598b8 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NativeContracts.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NativeContracts.cs @@ -114,6 +114,8 @@ public void Test_NEO() Assert.AreEqual("NEO", entry.GetString()); + // NeoSymbol + testengine.Reset(); result = testengine.ExecuteTestCaseStandard("nEOSymbol"); @@ -121,8 +123,20 @@ public void Test_NEO() Assert.AreEqual(1, result.Count); entry = result.Pop(); - Assert.AreEqual("neo", entry.GetString()); + + // NeoHash + + testengine.Reset(); + result = testengine.ExecuteTestCaseStandard("nEOHash"); + + Assert.AreEqual(VMState.HALT, testengine.State); + Assert.AreEqual(1, result.Count); + + entry = result.Pop(); + Assert.IsTrue(entry is VM.Types.ByteString); + var hash = new UInt160((VM.Types.ByteString)entry); + Assert.AreEqual(NativeContract.NEO.Hash, hash); } [TestMethod] diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StaticVar.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StaticVar.cs index b7cc7c91b..857245ffd 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StaticVar.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_StaticVar.cs @@ -1,6 +1,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Compiler.MSIL.UnitTests.Utils; using Neo.VM.Types; +using System; namespace Neo.Compiler.MSIL.UnitTests { @@ -23,7 +24,7 @@ public void Test_StaticVar() [TestMethod] public void Test_StaticVarInit() { - ByteString var1; + Neo.VM.Types.Buffer var1; ByteString var2; { var testengine = new TestEngine(); @@ -32,7 +33,7 @@ public void Test_StaticVarInit() // static byte[] callscript = ExecutionEngine.EntryScriptHash; // ... // return callscript - var1 = (result.Pop() as ByteString); + var1 = (result.Pop() as Neo.VM.Types.Buffer); } { var testengine = new TestEngine(); @@ -42,7 +43,7 @@ public void Test_StaticVarInit() var2 = (result.Pop() as ByteString); } Assert.IsNotNull(var1); - Assert.AreEqual(var1, var2); + Assert.IsTrue(var1.GetSpan().SequenceEqual(var2.GetSpan())); } } } diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Types.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Types.cs index f5b134a0c..5223116ff 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Types.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Types.cs @@ -1,7 +1,9 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Compiler.MSIL.UnitTests.Utils; +using Neo.IO; using Neo.VM; using Neo.VM.Types; +using Neo.Wallets; using System.Linq; namespace Neo.Compiler.MSIL.UnitTests @@ -351,5 +353,62 @@ public void delegate_Test() var item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Pointer)); } + + [TestMethod] + public void UInt160_equals_test() + { + var owner = "NiNmXL8FjEUEs1nfX9uHFBNaenxDHJtmuB".ToScriptHash(); + var notOwner = "NYjzhdekseMYWvYpSoAeypqMiwMuEUDhKB".ToScriptHash(); + + var testengine = new TestEngine(); + testengine.AddEntryScript("./TestClasses/Contract_UIntTypes.cs"); + + var result = testengine.ExecuteTestCaseStandard("checkOwner", owner.ToArray()); + Assert.AreEqual(1, result.Count); + var item = result.Pop(); + Assert.IsTrue(item.GetBoolean()); + + testengine.Reset(); + result = testengine.ExecuteTestCaseStandard("checkOwner", notOwner.ToArray()); + Assert.AreEqual(1, result.Count); + item = result.Pop(); + Assert.IsFalse(item.GetBoolean()); + } + + [TestMethod] + public void UInt160_equals_zero_test() + { + var zero = UInt160.Zero; + var notZero = "NYjzhdekseMYWvYpSoAeypqMiwMuEUDhKB".ToScriptHash(); + + var testengine = new TestEngine(); + testengine.AddEntryScript("./TestClasses/Contract_UIntTypes.cs"); + var result = testengine.ExecuteTestCaseStandard("checkZeroStatic", zero.ToArray()); + Assert.AreEqual(1, result.Count); + var item = result.Pop(); + Assert.IsTrue(item.GetBoolean()); + + testengine.Reset(); + result = testengine.ExecuteTestCaseStandard("checkZeroStatic", notZero.ToArray()); + Assert.AreEqual(1, result.Count); + item = result.Pop(); + Assert.IsFalse(item.GetBoolean()); + } + + [TestMethod] + public void UInt160_byte_array_construct() + { + var notZero = "NYjzhdekseMYWvYpSoAeypqMiwMuEUDhKB".ToScriptHash(); + + var testengine = new TestEngine(); + testengine.AddEntryScript("./TestClasses/Contract_UIntTypes.cs"); + + var result = testengine.ExecuteTestCaseStandard("constructUInt160", notZero.ToArray()); + Assert.AreEqual(1, result.Count); + var item = result.Pop(); + Assert.IsTrue(item is ByteString); + var received = new UInt160(((ByteString)item).GetSpan()); + Assert.AreEqual(received, notZero); + } } } diff --git a/tests/Neo.SmartContract.Framework.UnitTests/FeatureTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/FeatureTest.cs index 7fc60332e..bbb6b4017 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/FeatureTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/FeatureTest.cs @@ -1,6 +1,9 @@ +extern alias scfx; + using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Compiler.MSIL.UnitTests.Utils; using System.Linq; +using ContractFeatures = scfx.Neo.SmartContract.Framework.ContractFeatures; namespace Neo.SmartContract.Framework.UnitTests { diff --git a/tests/Neo.SmartContract.Framework.UnitTests/Neo.SmartContract.Framework.UnitTests.csproj b/tests/Neo.SmartContract.Framework.UnitTests/Neo.SmartContract.Framework.UnitTests.csproj index 41704ab3a..179204a92 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/Neo.SmartContract.Framework.UnitTests.csproj +++ b/tests/Neo.SmartContract.Framework.UnitTests/Neo.SmartContract.Framework.UnitTests.csproj @@ -15,6 +15,9 @@ + + scfx + diff --git a/tests/Neo.SmartContract.Framework.UnitTests/OpcodeTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/OpcodeTest.cs index 4871145b5..fc263caae 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/OpcodeTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/OpcodeTest.cs @@ -1,7 +1,9 @@ +extern alias scfx; + using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Linq; -using FrameworkOpCode = Neo.SmartContract.Framework.OpCode; +using FrameworkOpCode = scfx.Neo.SmartContract.Framework.OpCode; using VMOpCode = Neo.VM.OpCode; namespace Neo.SmartContract.Framework.UnitTests diff --git a/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/StaticStorageMapTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/StaticStorageMapTest.cs index b98b912d1..cdd560990 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/StaticStorageMapTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/StaticStorageMapTest.cs @@ -1,8 +1,11 @@ +extern alias scfx; + using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Compiler.MSIL.UnitTests.Utils; using Neo.Ledger; using Neo.VM; using System.Linq; +using ContractFeatures = scfx.Neo.SmartContract.Framework.ContractFeatures; namespace Neo.SmartContract.Framework.UnitTests.Services.Neo { diff --git a/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/StorageTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/StorageTest.cs index 7bf0b2aeb..400cf938d 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/StorageTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/StorageTest.cs @@ -1,9 +1,12 @@ +extern alias scfx; + using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Compiler.MSIL.UnitTests.Utils; using Neo.Ledger; using Neo.VM.Types; using System; using System.Linq; +using ContractFeatures = scfx.Neo.SmartContract.Framework.ContractFeatures; namespace Neo.SmartContract.Framework.UnitTests.Services.Neo { diff --git a/tests/Neo.SmartContract.Framework.UnitTests/Services/System/CallbackTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/Services/System/CallbackTest.cs index 5f46a605a..ba0ad9639 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/Services/System/CallbackTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/Services/System/CallbackTest.cs @@ -1,14 +1,16 @@ +extern alias scfx; + using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.Compiler.MSIL.UnitTests.Utils; using Neo.IO; using Neo.Ledger; using Neo.SmartContract; -using Neo.SmartContract.Framework.Services.System; using Neo.SmartContract.Framework.UnitTests; using Neo.SmartContract.Manifest; using Neo.VM; using Neo.VM.Types; using System.Linq; +using SyscallCallback = scfx.Neo.SmartContract.Framework.Services.System.SyscallCallback; namespace Neo.Compiler.MSIL.SmartContractFramework.Services.System { diff --git a/tests/Neo.SmartContract.Framework.UnitTests/Services/System/ExecutionEngineTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/Services/System/ExecutionEngineTest.cs index 3c4e3317a..d1f3f64ce 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/Services/System/ExecutionEngineTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/Services/System/ExecutionEngineTest.cs @@ -73,7 +73,7 @@ public void EntryScriptHashTest() Assert.AreEqual(1, result.Count); var item = result.Pop(); - Assert.IsInstanceOfType(item, typeof(VM.Types.ByteString)); + Assert.IsInstanceOfType(item, typeof(VM.Types.Buffer)); //test by this way is bad idea? how to sure got a fix hash always? var gothash = item.GetSpan().ToHexString(); Assert.AreEqual(scriptHash, gothash); @@ -88,7 +88,7 @@ public void ExecutingScriptHashTest() Assert.AreEqual(1, result.Count); var item = result.Pop(); - Assert.IsInstanceOfType(item, typeof(VM.Types.ByteString)); + Assert.IsInstanceOfType(item, typeof(VM.Types.Buffer)); //test by this way is bad idea? how to sure got a fix hash always? var gothash = item.GetSpan().ToHexString(); Assert.AreEqual(scriptHash, gothash); diff --git a/tests/Neo.SmartContract.Framework.UnitTests/StackItemTypeTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/StackItemTypeTest.cs index 978abf6c0..24ed4e232 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/StackItemTypeTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/StackItemTypeTest.cs @@ -1,5 +1,8 @@ +extern alias scfx; + using Microsoft.VisualStudio.TestTools.UnitTesting; using Neo.VM.Types; +using scfxStackItemType = scfx.Neo.SmartContract.Framework.StackItemType; namespace Neo.SmartContract.Framework.UnitTests { @@ -9,8 +12,8 @@ public class StackItemTypeTest [TestMethod] public void TestValues() { - Assert.AreEqual(((byte)VM.Types.StackItemType.Buffer).ToString("x2"), StackItemType.Buffer.Substring(2)); - Assert.AreEqual(((byte)VM.Types.StackItemType.Integer).ToString("x2"), StackItemType.Integer.Substring(2)); + Assert.AreEqual(((byte)VM.Types.StackItemType.Buffer).ToString("x2"), scfxStackItemType.Buffer.Substring(2)); + Assert.AreEqual(((byte)VM.Types.StackItemType.Integer).ToString("x2"), scfxStackItemType.Integer.Substring(2)); } } } diff --git a/tests/Neo.SmartContract.Framework.UnitTests/SyscallCallbackTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/SyscallCallbackTest.cs index cb292eb24..4987aab32 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/SyscallCallbackTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/SyscallCallbackTest.cs @@ -1,7 +1,9 @@ +extern alias scfx; + using Microsoft.VisualStudio.TestTools.UnitTesting; -using Neo.SmartContract.Framework.Services.System; using System; using System.Collections.Generic; +using SyscallCallback = scfx.Neo.SmartContract.Framework.Services.System.SyscallCallback; namespace Neo.SmartContract.Framework.UnitTests { diff --git a/tests/Neo.SmartContract.Framework.UnitTests/SyscallTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/SyscallTest.cs index eca2cc63a..6194edc29 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/SyscallTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/SyscallTest.cs @@ -1,7 +1,11 @@ +extern alias scfx; + using Microsoft.VisualStudio.TestTools.UnitTesting; using Mono.Cecil; using System.Collections.Generic; using System.IO; +using SyscallAttribute = scfx.Neo.SmartContract.Framework.SyscallAttribute; +using scfxSmartContract = scfx.Neo.SmartContract.Framework.SmartContract; namespace Neo.SmartContract.Framework.UnitTests { @@ -15,7 +19,7 @@ public void TestAllSyscalls() var list = new HashSet(); - using (var stream = File.OpenRead(typeof(SmartContract).Assembly.Location)) + using (var stream = File.OpenRead(typeof(scfxSmartContract).Assembly.Location)) { var expectedType = typeof(SyscallAttribute).FullName; var module = ModuleDefinition.ReadModule(stream); diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Account.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Account.cs index 93daa9da3..929fb4915 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Account.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Account.cs @@ -4,7 +4,7 @@ namespace Neo.Compiler.MSIL.TestClasses { public class Contract_Account : SmartContract.Framework.SmartContract { - public static bool AccountIsStandard(byte[] scripthash) + public static bool AccountIsStandard(UInt160 scripthash) { return Account.IsStandard(scripthash); } diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Blockchain.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Blockchain.cs index 57f3ac285..b505cb35b 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Blockchain.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Blockchain.cs @@ -11,12 +11,12 @@ public static uint GetHeight() return Blockchain.GetHeight(); } - public static BigInteger GetTransactionHeight(byte[] hash) + public static BigInteger GetTransactionHeight(UInt256 hash) { return Blockchain.GetTransactionHeight(hash); } - public static object GetBlockByHash(byte[] hash, string whatReturn) + public static object GetBlockByHash(UInt256 hash, string whatReturn) { var block = Blockchain.GetBlock(hash); return GetBlockInfo(block, whatReturn); @@ -48,13 +48,13 @@ private static object GetBlockInfo(Block block, string whatReturn) throw new Exception("Uknown property"); } - public static object GetTxByHash(byte[] hash, string whatReturn) + public static object GetTxByHash(UInt256 hash, string whatReturn) { var tx = Blockchain.GetTransaction(hash); return GetTxInfo(tx, whatReturn); } - public static object GetTxByBlockHash(byte[] blockHash, int txIndex, string whatReturn) + public static object GetTxByBlockHash(UInt256 blockHash, int txIndex, string whatReturn) { var tx = Blockchain.GetTransactionFromBlock(blockHash, txIndex); return GetTxInfo(tx, whatReturn); @@ -86,7 +86,7 @@ private static object GetTxInfo(Transaction tx, string whatReturn) throw new Exception("Uknown property"); } - public static object GetContract(byte[] hash, string whatReturn) + public static object GetContract(UInt160 hash, string whatReturn) { var contract = Blockchain.GetContract(hash); return GetContractInfo(contract, whatReturn); diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Callback.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Callback.cs index be360606b..a841810f4 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Callback.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Callback.cs @@ -15,12 +15,12 @@ public static object test2(object args) return 123; } - public static object createFromMethod(byte[] hash, string method) + public static object createFromMethod(UInt160 hash, string method) { return Callback.CreateFromMethod(hash, method); } - public static object createAndCallFromMethod(byte[] hash, string method) + public static object createAndCallFromMethod(UInt160 hash, string method) { return Callback.CreateFromMethod(hash, method).Invoke(new object[0]); } diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Contract.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Contract.cs index e4738d49d..33c897562 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Contract.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Contract.cs @@ -4,7 +4,7 @@ namespace Neo.Compiler.MSIL.TestClasses { public class Contract_Contract : SmartContract.Framework.SmartContract { - public static object Call(byte[] scriptHash, string method, object[] arguments) + public static object Call(UInt160 scriptHash, string method, object[] arguments) { return Contract.Call(scriptHash, method, arguments); } @@ -29,7 +29,7 @@ public static int GetCallFlags() return Contract.GetCallFlags(); } - public static byte[] CreateStandardAccount(byte[] pubKey) + public static UInt160 CreateStandardAccount(Cryptography.ECC.ECPoint pubKey) { return Contract.CreateStandardAccount(pubKey); } diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Crypto.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Crypto.cs index 879040d25..7bfcd77ff 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Crypto.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Crypto.cs @@ -1,3 +1,4 @@ +using Neo.Cryptography.ECC; using Neo.SmartContract.Framework.Services.Neo; using System.ComponentModel; @@ -27,42 +28,42 @@ public static byte[] Hash256(byte[] value) return Crypto.Hash256(value); } - public static bool Secp256r1VerifySignature(byte[] pubkey, byte[] signature) + public static bool Secp256r1VerifySignature(ECPoint pubkey, byte[] signature) { return Crypto.ECDsa.Secp256r1.Verify(null, pubkey, signature); } - public static bool Secp256r1VerifySignatureWithMessage(byte[] message, byte[] pubkey, byte[] signature) + public static bool Secp256r1VerifySignatureWithMessage(byte[] message, ECPoint pubkey, byte[] signature) { return Crypto.ECDsa.Secp256r1.Verify(message, pubkey, signature); } - public static bool Secp256r1VerifySignatures(byte[][] pubkeys, byte[][] signatures) + public static bool Secp256r1VerifySignatures(ECPoint[] pubkeys, byte[][] signatures) { return Crypto.ECDsa.Secp256r1.CheckMultiSig(null, pubkeys, signatures); } - public static bool Secp256r1VerifySignaturesWithMessage(byte[] message, byte[][] pubkeys, byte[][] signatures) + public static bool Secp256r1VerifySignaturesWithMessage(byte[] message, ECPoint[] pubkeys, byte[][] signatures) { return Crypto.ECDsa.Secp256r1.CheckMultiSig(message, pubkeys, signatures); } - public static bool Secp256k1VerifySignature(byte[] pubkey, byte[] signature) + public static bool Secp256k1VerifySignature(ECPoint pubkey, byte[] signature) { return Crypto.ECDsa.Secp256k1.Verify(null, pubkey, signature); } - public static bool Secp256k1VerifySignatureWithMessage(byte[] message, byte[] pubkey, byte[] signature) + public static bool Secp256k1VerifySignatureWithMessage(byte[] message, ECPoint pubkey, byte[] signature) { return Crypto.ECDsa.Secp256k1.Verify(message, pubkey, signature); } - public static bool Secp256k1VerifySignatures(byte[][] pubkeys, byte[][] signatures) + public static bool Secp256k1VerifySignatures(ECPoint[] pubkeys, byte[][] signatures) { return Crypto.ECDsa.Secp256k1.CheckMultiSig(null, pubkeys, signatures); } - public static bool Secp256k1VerifySignaturesWithMessage(byte[] message, byte[][] pubkeys, byte[][] signatures) + public static bool Secp256k1VerifySignaturesWithMessage(byte[] message, ECPoint[] pubkeys, byte[][] signatures) { return Crypto.ECDsa.Secp256k1.CheckMultiSig(message, pubkeys, signatures); } diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_ExecutionEngine.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_ExecutionEngine.cs index b21025ca9..baf160d33 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_ExecutionEngine.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_ExecutionEngine.cs @@ -6,17 +6,17 @@ public class Contract_ExecutionEngine : SmartContract.Framework.SmartContract { public static byte[] CallingScriptHash() { - return ExecutionEngine.CallingScriptHash; + return (byte[])ExecutionEngine.CallingScriptHash; } public static byte[] EntryScriptHash() { - return ExecutionEngine.EntryScriptHash; + return (byte[])ExecutionEngine.EntryScriptHash; } public static byte[] ExecutingScriptHash() { - return ExecutionEngine.ExecutingScriptHash; + return (byte[])ExecutionEngine.ExecutingScriptHash; } public static object ScriptContainer() diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Helper.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Helper.cs index 03970dfc7..05033d6cb 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Helper.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Helper.cs @@ -5,8 +5,8 @@ namespace Compiler.MSIL.TestClasses { public class Contract_Helper : SmartContract { - static readonly byte[] data = "0a0b0c0d0E0F".HexToBytes(); - static readonly byte[] hashResult = "AFsCjUGzicZmXQtWpwVt6hNeJTBwSipJMS".ToScriptHash(); + static readonly byte[] data = (byte[])"0a0b0c0d0E0F".HexToBytes(); + static readonly byte[] hashResult = (byte[])"AFsCjUGzicZmXQtWpwVt6hNeJTBwSipJMS".ToScriptHash(); public static byte[] TestHexToBytes() { diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Native.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Native.cs index 3690e36c8..7e708f2ee 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Native.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Native.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using System.Numerics; using System; +using Neo.Cryptography.ECC; namespace Neo.Compiler.MSIL.TestClasses { @@ -20,13 +21,13 @@ public static string NEO_Name() } [DisplayName("NEO_Transfer")] - public static bool NEO_Transfer(byte[] from, byte[] to, BigInteger amount) + public static bool NEO_Transfer(UInt160 from, UInt160 to, BigInteger amount) { return NEO.Transfer(from, to, amount); } [DisplayName("NEO_BalanceOf")] - public static BigInteger NEO_BalanceOf(byte[] account) + public static BigInteger NEO_BalanceOf(UInt160 account) { return NEO.BalanceOf(account); } @@ -38,19 +39,19 @@ public static BigInteger NEO_GetGasPerBlock() } [DisplayName("NEO_UnclaimedGas")] - public static BigInteger NEO_UnclaimedGas(byte[] account, uint end) + public static BigInteger NEO_UnclaimedGas(UInt160 account, uint end) { return NEO.UnclaimedGas(account, end); } [DisplayName("NEO_RegisterCandidate")] - public static bool NEO_RegisterCandidate(byte[] pubkey) + public static bool NEO_RegisterCandidate(ECPoint pubkey) { return NEO.RegisterCandidate(pubkey); } [DisplayName("NEO_GetCandidates")] - public static (string, BigInteger)[] NEO_GetCandidates() + public static (ECPoint, BigInteger)[] NEO_GetCandidates() { return NEO.GetCandidates(); } @@ -80,7 +81,7 @@ public static uint Policy_GetMaxTransactionsPerBlock() } [DisplayName("Policy_IsBlocked")] - public static object[] Policy_IsBlocked(byte[] account) + public static object[] Policy_IsBlocked(UInt160 account) { return Policy.IsBlocked(account); } diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Runtime.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Runtime.cs index 8cb1986a0..0a75387eb 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Runtime.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_Runtime.cs @@ -34,12 +34,12 @@ public static void Log(string message) Runtime.Log(message); } - public static bool CheckWitness(byte[] hashOrPubkey) + public static bool CheckWitness(UInt160 hash) { - return Runtime.CheckWitness(hashOrPubkey); + return Runtime.CheckWitness(hash); } - public static int GetNotificationsCount(byte[] hash) + public static int GetNotificationsCount(UInt160 hash) { var notifications = Runtime.GetNotifications(hash); return notifications.Length; @@ -59,23 +59,14 @@ public static int GetAllNotifications() return sum; } - public static int GetNotifications(byte[] hash) + public static int GetNotifications(UInt160 hash) { int sum = 0; var notifications = Runtime.GetNotifications(hash); for (int x = 0; x < notifications.Length; x++) { - var notify = notifications[x]; - - // Check that the hash is working well - - for (int y = 0; y < notify.ScriptHash.Length; y++) - { - if (notify.ScriptHash[y] != hash[y]) return int.MinValue; - } - - sum += (int)notify.State[0]; + sum += (int)notifications[x].State[0]; } return sum; diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_SupportedStandards.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_SupportedStandards.cs index 7591a0828..4fec25b1d 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_SupportedStandards.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_SupportedStandards.cs @@ -6,7 +6,7 @@ namespace Neo.Compiler.MSIL.TestClasses [SupportedStandards("NEP10","NEP5")] public class Contract_SupportedStandards : SmartContract.Framework.SmartContract { - public static bool AccountIsStandard(byte[] scripthash) + public static bool AccountIsStandard(UInt160 scripthash) { return Account.IsStandard(scripthash); } diff --git a/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_UInt.cs b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_UInt.cs new file mode 100644 index 000000000..51494ee11 --- /dev/null +++ b/tests/Neo.SmartContract.Framework.UnitTests/TestClasses/Contract_UInt.cs @@ -0,0 +1,15 @@ +namespace Neo.Compiler.MSIL.TestClasses +{ + public class Contract_UInt : SmartContract.Framework.SmartContract + { + public static bool IsZeroUInt256(UInt256 value) + { + return value.IsZero; + } + + public static bool IsZeroUInt160(UInt160 value) + { + return value.IsZero; + } + } +} diff --git a/tests/Neo.SmartContract.Framework.UnitTests/UIntTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/UIntTest.cs new file mode 100644 index 000000000..6a9974ed2 --- /dev/null +++ b/tests/Neo.SmartContract.Framework.UnitTests/UIntTest.cs @@ -0,0 +1,38 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Compiler.MSIL.UnitTests.Utils; +using Neo.IO; + +namespace Neo.SmartContract.Framework.UnitTests +{ + [TestClass] + public class UIntTest + { + private TestEngine _engine; + + [TestInitialize] + public void Init() + { + _engine = new TestEngine(); + _engine.AddEntryScript("./TestClasses/Contract_UInt.cs"); + } + + [TestMethod] + public void TestStringAdd() + { + var result = _engine.ExecuteTestCaseStandard("isZeroUInt256", UInt256.Zero.ToArray()); + Assert.IsTrue(result.Pop().GetBoolean()); + + _engine.Reset(); + result = _engine.ExecuteTestCaseStandard("isZeroUInt160", UInt160.Zero.ToArray()); + Assert.IsTrue(result.Pop().GetBoolean()); + + _engine.Reset(); + result = _engine.ExecuteTestCaseStandard("isZeroUInt256", UInt256.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff01").ToArray()); + Assert.IsFalse(result.Pop().GetBoolean()); + + _engine.Reset(); + result = _engine.ExecuteTestCaseStandard("isZeroUInt160", UInt160.Parse("01ff00ff00ff00ff00ff00ff00ff00ff00ff00a4").ToArray()); + Assert.IsFalse(result.Pop().GetBoolean()); + } + } +}