Skip to content

Commit

Permalink
Add ContractCall and UTs, delete Appcall (#327)
Browse files Browse the repository at this point in the history
* add ConTractCall and UTs, delete Appcall

* fix

* Disable warnings

* spilt and fix

* del ID

* fix Neo and Policy, Add UT

* del blank line

* fix internal

Co-authored-by: erikzhang <[email protected]>
Co-authored-by: Shargon <[email protected]>
  • Loading branch information
3 people authored Jul 29, 2020
1 parent ea65ad0 commit 742945c
Show file tree
Hide file tree
Showing 16 changed files with 334 additions and 120 deletions.
30 changes: 23 additions & 7 deletions src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,17 @@ public bool IsSysCall(Mono.Cecil.MethodDefinition defs, out string name)
}
*/

public bool IsAppCall(Mono.Cecil.MethodDefinition defs, out byte[] hash)
public bool IsContractCall(Mono.Cecil.MethodDefinition defs, out byte[] hash)
{
if (defs == null)
{
hash = null;
return false;
}

foreach (var attr in defs.CustomAttributes)
foreach (var attr in defs.DeclaringType.CustomAttributes)
{
if (attr.AttributeType.Name == "AppcallAttribute")
if (attr.AttributeType.Name == "ContractAttribute")
{
var type = attr.ConstructorArguments[0].Type;
var a = attr.ConstructorArguments[0];
Expand Down Expand Up @@ -462,16 +462,18 @@ private int ConvertCall(OpCode src, NeoMethod to)
calltype = 2;
}
}
else if (IsAppCall(defs, out callhash))
else if (IsContractCall(defs, out callhash))
{
calltype = 4;
}
else if (this.outModule.mapMethods.ContainsKey(src.tokenMethod))
{//this is a call
{
//this is a call
calltype = 1;
}
else
{//maybe a syscall // or other
{
//maybe a syscall // or other
if (src.tokenMethod.Contains("::op_Explicit(") || src.tokenMethod.Contains("::op_Implicit("))
{
//All types of display implicit conversion are ignored
Expand Down Expand Up @@ -738,7 +740,8 @@ private int ConvertCall(OpCode src, NeoMethod to)
//opcode call
}
else
{// reverse the arguments order
{
// reverse the arguments order

//this become very diffcult

Expand Down Expand Up @@ -829,8 +832,21 @@ 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);

// Push call method name, the first letter should be lowercase.
var methodName = defs.Body.Method.Name;
ConvertPushString(methodName[..1].ToLowerInvariant() + methodName[1..], src, to);

// Push contract hash.
ConvertPushDataArray(callhash, 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);
}
else if (calltype == 5)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.Compiler.MSIL/MSIL/Converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public NeoModule Convert(ILModule _in, ConvOption option = null)
nm.paramtypes.Add(new NeoParam(src.name, src.type));
}

if (IsAppCall(m.Value.method, out byte[] outcall))
if (IsContractCall(m.Value.method, out byte[] outcall))
continue;
if (IsNonCall(m.Value.method))
continue;
Expand Down
33 changes: 0 additions & 33 deletions src/Neo.SmartContract.Framework/AppcallAttribute.cs

This file was deleted.

33 changes: 33 additions & 0 deletions src/Neo.SmartContract.Framework/ContractAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Globalization;

namespace Neo.SmartContract.Framework
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ContractAttribute : Attribute
{
public byte[] Hash { get; }

public ContractAttribute(byte[] hash)
{
if (hash == null) throw new ArgumentNullException();
if (hash.Length != 20) throw new ArgumentException();
Hash = hash;
}

public ContractAttribute(string hash)
{
if (hash == null) throw new ArgumentNullException();

if (hash.StartsWith("0x"))
{
hash = hash.Remove(0, 2);
}

if (hash.Length != 40) throw new ArgumentException();
Hash = new byte[hash.Length / 2];
for (int i = 0; i < Hash.Length; i++)
Hash[i] = byte.Parse(hash.Substring(i * 2, 2), NumberStyles.AllowHexSpecifier);
}
}
}
16 changes: 16 additions & 0 deletions src/Neo.SmartContract.Framework/Services/Neo/GAS.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma warning disable CS0626

using System.Numerics;

namespace Neo.SmartContract.Framework.Services.Neo
{
[Contract("0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc")]
public class GAS
{
public static extern string Name();
public static extern string Symbol();
public static extern byte Decimals();
public static extern BigInteger TotalSupply();
public static extern BigInteger BalanceOf(byte[] account);
}
}
27 changes: 27 additions & 0 deletions src/Neo.SmartContract.Framework/Services/Neo/NEO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma warning disable CS0626

using System;
using System.Numerics;

namespace Neo.SmartContract.Framework.Services.Neo
{
[Contract("0xde5f57d430d3dece511cf975a8d37848cb9e0525")]
public class NEO
{
public static extern string Name();
public static extern string Symbol();
public static extern BigInteger Decimals();
public static extern BigInteger TotalSupply();
public static extern BigInteger BalanceOf(byte[] account);

public static extern BigInteger UnclaimedGas(byte[] 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[] GetValidators();
public static extern string[] GetCommittee();
public static extern string[] GetNextBlockValidators();
}
}
14 changes: 0 additions & 14 deletions src/Neo.SmartContract.Framework/Services/Neo/Native.cs

This file was deleted.

24 changes: 24 additions & 0 deletions src/Neo.SmartContract.Framework/Services/Neo/Policy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma warning disable CS0626

using System;
using System.Numerics;

namespace Neo.SmartContract.Framework.Services.Neo
{
[Contract("0xce06595079cd69583126dbfd1d2e25cca74cffe9")]
public class Policy
{
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[] GetBlockedAccounts();
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);
}
}
11 changes: 11 additions & 0 deletions tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,16 @@ public static byte[] unitTest_001()
return nb;
}

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

public static byte[] testArgs(byte a)
{
var nb = new byte[] { 1, 2, 3, 3 };
nb[3] = a;
return nb;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Neo.SmartContract.Framework;

namespace Neo.Compiler.MSIL.UnitTests.TestClasses
{
[Contract("0102030405060708090A0102030405060708090A")]
public class Contract1
{
public static extern byte[] testArgs(byte a);
public static extern void testVoid();
}

public class Contract_ContractCall : SmartContract.Framework.SmartContract
{
public static byte[] testContractCall()
{
return Contract1.testArgs((byte)4);
}

public static void testContractCallVoid()
{
Contract1.testVoid();
}
}
}
20 changes: 0 additions & 20 deletions tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_appcall.cs

This file was deleted.

34 changes: 0 additions & 34 deletions tests/Neo.Compiler.MSIL.UnitTests/UnitTest_Appcall.cs

This file was deleted.

49 changes: 49 additions & 0 deletions tests/Neo.Compiler.MSIL.UnitTests/UnitTest_ContractCall.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Compiler.MSIL.UnitTests.Utils;
using Neo.IO.Json;
using Neo.SmartContract.Manifest;
using Neo.VM;
using Neo.VM.Types;

namespace Neo.Compiler.MSIL.UnitTests
{
[TestClass]
public class UnitTest_ContractCall
{
private TestEngine _engine;

[TestInitialize]
public void Init()
{
var hash = UInt160.Parse("0102030405060708090A0102030405060708090A");
_engine = new TestEngine();
_engine.Snapshot.Contracts.Add(hash, new Ledger.ContractState()
{
Script = _engine.Build("./TestClasses/Contract1.cs").finalNEF,
Manifest = ContractManifest.FromJson(JObject.Parse(_engine.Build("./TestClasses/Contract1.cs").finalManifest)),
});

//will ContractCall 0102030405060708090A0102030405060708090A
_engine.AddEntryScript("./TestClasses/Contract_ContractCall.cs");
}

[TestMethod]
public void Test_ContractCall()
{
var result = _engine.GetMethod("testContractCall").Run().ConvertTo(StackItemType.ByteString);
Assert.AreEqual(VMState.HALT, _engine.State);

StackItem wantresult = new byte[] { 1, 2, 3, 4 };
var bequal = wantresult.Equals(result);
Assert.IsTrue(bequal);
}

[TestMethod]
public void Test_ContractCall_Void()
{
var result = _engine.ExecuteTestCaseStandard("testContractCallVoid");
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(0, result.Count);
}
}
}
2 changes: 2 additions & 0 deletions tests/Neo.Compiler.MSIL.UnitTests/Utils/NeonTestTool.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Neo.VM;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;

[assembly: InternalsVisibleTo("Neo.SmartContract.Framework.UnitTests")]
namespace Neo.Compiler.MSIL.UnitTests.Utils
{
internal static class NeonTestTool
Expand Down
Loading

0 comments on commit 742945c

Please sign in to comment.