From dadfde47926dac518f88282e7e46802a0e0b2b54 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Wed, 3 Jun 2020 14:53:54 +0800 Subject: [PATCH] Check return value of contracts --- src/neo/Ledger/Blockchain.cs | 2 +- .../ApplicationEngine.Contract.cs | 18 ++++--- src/neo/SmartContract/ApplicationEngine.cs | 15 ++++-- .../SmartContract/ContractParameterType.cs | 25 +++++----- .../SmartContract/ExecutionContextState.cs | 2 + .../SmartContract/Native/NativeContract.cs | 2 +- src/neo/VM/Helper.cs | 15 +++--- src/neo/Wallets/AssetDescriptor.cs | 4 +- src/neo/Wallets/Wallet.cs | 8 +-- src/neo/neo.csproj | 2 +- .../Network/P2P/Payloads/UT_Transaction.cs | 40 +++++++-------- .../Native/Tokens/UT_NeoToken.cs | 2 +- .../SmartContract/UT_InteropService.cs | 20 ++++---- .../SmartContract/UT_Syscalls.cs | 8 +-- tests/neo.UnitTests/VM/UT_Helper.cs | 49 ++++++++++--------- .../Wallets/SQLite/UT_VerificationContract.cs | 2 +- 16 files changed, 118 insertions(+), 96 deletions(-) diff --git a/src/neo/Ledger/Blockchain.cs b/src/neo/Ledger/Blockchain.cs index b10a60e870..b937d8c0a4 100644 --- a/src/neo/Ledger/Blockchain.cs +++ b/src/neo/Ledger/Blockchain.cs @@ -91,7 +91,7 @@ static Blockchain() using (ScriptBuilder sb = new ScriptBuilder()) { foreach (NativeContract contract in contracts) - sb.EmitAppCall(contract.Hash, "onPersist"); + sb.EmitAppCall(contract.Hash, ContractParameterType.Boolean, "onPersist"); onPersistNativeContractScript = sb.ToArray(); } diff --git a/src/neo/SmartContract/ApplicationEngine.Contract.cs b/src/neo/SmartContract/ApplicationEngine.Contract.cs index 31407a596c..5331e9096c 100644 --- a/src/neo/SmartContract/ApplicationEngine.Contract.cs +++ b/src/neo/SmartContract/ApplicationEngine.Contract.cs @@ -100,19 +100,19 @@ internal void DestroyContract() Snapshot.Storages.Delete(key); } - internal void CallContract(UInt160 contractHash, string method, Array args) + internal void CallContract(UInt160 contractHash, ContractParameterType returnType, string method, Array args) { - CallContractInternal(contractHash, method, args, CallFlags.All); + CallContractInternal(contractHash, returnType, method, args, CallFlags.All); } - internal void CallContractEx(UInt160 contractHash, string method, Array args, CallFlags callFlags) + internal void CallContractEx(UInt160 contractHash, ContractParameterType returnType, string method, Array args, CallFlags callFlags) { if ((callFlags & ~CallFlags.All) != 0) throw new ArgumentOutOfRangeException(nameof(callFlags)); - CallContractInternal(contractHash, method, args, callFlags); + CallContractInternal(contractHash, returnType, method, args, callFlags); } - private void CallContractInternal(UInt160 contractHash, string method, Array args, CallFlags flags) + private void CallContractInternal(UInt160 contractHash, ContractParameterType returnType, string method, Array args, CallFlags flags) { if (method.StartsWith('_')) throw new ArgumentException(); @@ -139,11 +139,15 @@ private void CallContractInternal(UInt160 contractHash, string method, Array arg ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod(method); if (md is null) throw new InvalidOperationException(); - int rvcount = md.ReturnType == ContractParameterType.Void ? 0 : 1; - ExecutionContext context_new = LoadScript(contract.Script, rvcount); + if (returnType == ContractParameterType.Void && md.ReturnType != ContractParameterType.Void) + throw new InvalidOperationException(); + if (returnType != ContractParameterType.Any && md.ReturnType != returnType) + throw new InvalidOperationException(); + ExecutionContext context_new = LoadScript(contract.Script); state = context_new.GetState(); state.CallingScriptHash = callingScriptHash; state.CallFlags = flags & callingFlags; + state.RVCount = returnType == ContractParameterType.Void ? 0 : 1; if (NativeContract.IsNative(contractHash)) { diff --git a/src/neo/SmartContract/ApplicationEngine.cs b/src/neo/SmartContract/ApplicationEngine.cs index 11708d9609..6c9abb55fd 100644 --- a/src/neo/SmartContract/ApplicationEngine.cs +++ b/src/neo/SmartContract/ApplicationEngine.cs @@ -55,6 +55,15 @@ internal bool AddGas(long gas) return testMode || GasConsumed <= gas_amount; } + protected override void ContextUnloaded(ExecutionContext context) + { + base.ContextUnloaded(context); + if (context.EvaluationStack == CurrentContext?.EvaluationStack) return; + int rvcount = context.GetState().RVCount; + if (rvcount != -1 && rvcount != context.EvaluationStack.Count) + throw new InvalidOperationException(); + } + protected override void LoadContext(ExecutionContext context) { // Set default execution context state @@ -64,9 +73,9 @@ protected override void LoadContext(ExecutionContext context) base.LoadContext(context); } - public ExecutionContext LoadScript(Script script, CallFlags callFlags, int rvcount = -1) + public ExecutionContext LoadScript(Script script, CallFlags callFlags) { - ExecutionContext context = LoadScript(script, rvcount); + ExecutionContext context = LoadScript(script); context.GetState().CallFlags = callFlags; return context; } @@ -144,7 +153,7 @@ protected override bool OnSysCall(uint method) { value = pd.Converter(item); if (pd.IsEnum) - value = Convert.ChangeType(value, pd.Type); + value = Enum.ToObject(pd.Type, value); else if (pd.IsInterface) value = ((InteropInterface)value).GetInterface(); } diff --git a/src/neo/SmartContract/ContractParameterType.cs b/src/neo/SmartContract/ContractParameterType.cs index 748ff86654..f7592ba7d1 100644 --- a/src/neo/SmartContract/ContractParameterType.cs +++ b/src/neo/SmartContract/ContractParameterType.cs @@ -2,21 +2,22 @@ namespace Neo.SmartContract { public enum ContractParameterType : byte { - Signature = 0x00, - Boolean = 0x01, - Integer = 0x02, - Hash160 = 0x03, - Hash256 = 0x04, - ByteArray = 0x05, - PublicKey = 0x06, - String = 0x07, + Any = 0x00, - Array = 0x10, - Map = 0x12, + Boolean = 0x10, + Integer = 0x11, + ByteArray = 0x12, + String = 0x13, + Hash160 = 0x14, + Hash256 = 0x15, + PublicKey = 0x16, + Signature = 0x17, - InteropInterface = 0xf0, + Array = 0x20, + Map = 0x22, + + InteropInterface = 0x30, - Any = 0xfe, Void = 0xff } } diff --git a/src/neo/SmartContract/ExecutionContextState.cs b/src/neo/SmartContract/ExecutionContextState.cs index 7c5aca4231..d31b411720 100644 --- a/src/neo/SmartContract/ExecutionContextState.cs +++ b/src/neo/SmartContract/ExecutionContextState.cs @@ -16,5 +16,7 @@ internal class ExecutionContextState /// Execution context rights /// public CallFlags CallFlags { get; set; } = CallFlags.All; + + public int RVCount { get; set; } = -1; } } diff --git a/src/neo/SmartContract/Native/NativeContract.cs b/src/neo/SmartContract/Native/NativeContract.cs index c42d7eb439..547f105d4c 100644 --- a/src/neo/SmartContract/Native/NativeContract.cs +++ b/src/neo/SmartContract/Native/NativeContract.cs @@ -161,7 +161,7 @@ public ApplicationEngine TestCall(string operation, params object[] args) { using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitAppCall(Hash, operation, args); + sb.EmitAppCall(Hash, ContractParameterType.Any, operation, args); return ApplicationEngine.Run(sb.ToArray(), testMode: true); } } diff --git a/src/neo/VM/Helper.cs b/src/neo/VM/Helper.cs index c99ad135f2..22a36b0345 100644 --- a/src/neo/VM/Helper.cs +++ b/src/neo/VM/Helper.cs @@ -23,35 +23,38 @@ public static ScriptBuilder Emit(this ScriptBuilder sb, params OpCode[] ops) return sb; } - public static ScriptBuilder EmitAppCall(this ScriptBuilder sb, UInt160 scriptHash, string operation) + public static ScriptBuilder EmitAppCall(this ScriptBuilder sb, UInt160 scriptHash, ContractParameterType returnType, string operation) { sb.EmitPush(0); sb.Emit(OpCode.NEWARRAY); sb.EmitPush(operation); + sb.EmitPush(returnType); sb.EmitPush(scriptHash); sb.EmitSysCall(ApplicationEngine.System_Contract_Call); return sb; } - public static ScriptBuilder EmitAppCall(this ScriptBuilder sb, UInt160 scriptHash, string operation, params ContractParameter[] args) + public static ScriptBuilder EmitAppCall(this ScriptBuilder sb, UInt160 scriptHash, ContractParameterType returnType, string operation, params ContractParameter[] args) { for (int i = args.Length - 1; i >= 0; i--) sb.EmitPush(args[i]); sb.EmitPush(args.Length); sb.Emit(OpCode.PACK); sb.EmitPush(operation); + sb.EmitPush(returnType); sb.EmitPush(scriptHash); sb.EmitSysCall(ApplicationEngine.System_Contract_Call); return sb; } - public static ScriptBuilder EmitAppCall(this ScriptBuilder sb, UInt160 scriptHash, string operation, params object[] args) + public static ScriptBuilder EmitAppCall(this ScriptBuilder sb, UInt160 scriptHash, ContractParameterType returnType, string operation, params object[] args) { for (int i = args.Length - 1; i >= 0; i--) sb.EmitPush(args[i]); sb.EmitPush(args.Length); sb.Emit(OpCode.PACK); sb.EmitPush(operation); + sb.EmitPush(returnType); sb.EmitPush(scriptHash); sb.EmitSysCall(ApplicationEngine.System_Contract_Call); return sb; @@ -208,14 +211,14 @@ public static string GetString(this StackItem item) /// contract operation /// operation arguments /// - public static byte[] MakeScript(this UInt160 scriptHash, string operation, params object[] args) + public static byte[] MakeScript(this UInt160 scriptHash, ContractParameterType returnType, string operation, params object[] args) { using (ScriptBuilder sb = new ScriptBuilder()) { if (args.Length > 0) - sb.EmitAppCall(scriptHash, operation, args); + sb.EmitAppCall(scriptHash, returnType, operation, args); else - sb.EmitAppCall(scriptHash, operation); + sb.EmitAppCall(scriptHash, returnType, operation); return sb.ToArray(); } } diff --git a/src/neo/Wallets/AssetDescriptor.cs b/src/neo/Wallets/AssetDescriptor.cs index 46a80a0f5c..a12cd280bd 100644 --- a/src/neo/Wallets/AssetDescriptor.cs +++ b/src/neo/Wallets/AssetDescriptor.cs @@ -15,8 +15,8 @@ public AssetDescriptor(UInt160 asset_id) byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitAppCall(asset_id, "decimals"); - sb.EmitAppCall(asset_id, "name"); + sb.EmitAppCall(asset_id, ContractParameterType.Integer, "decimals"); + sb.EmitAppCall(asset_id, ContractParameterType.String, "name"); script = sb.ToArray(); } using ApplicationEngine engine = ApplicationEngine.Run(script, extraGAS: 3_000_000); diff --git a/src/neo/Wallets/Wallet.cs b/src/neo/Wallets/Wallet.cs index def6977959..1a2cdefa0e 100644 --- a/src/neo/Wallets/Wallet.cs +++ b/src/neo/Wallets/Wallet.cs @@ -137,10 +137,10 @@ public BigDecimal GetBalance(UInt160 asset_id, params UInt160[] accounts) sb.EmitPush(0); foreach (UInt160 account in accounts) { - sb.EmitAppCall(asset_id, "balanceOf", account); + sb.EmitAppCall(asset_id, ContractParameterType.Integer, "balanceOf", account); sb.Emit(OpCode.ADD); } - sb.EmitAppCall(asset_id, "decimals"); + sb.EmitAppCall(asset_id, ContractParameterType.Integer, "decimals"); script = sb.ToArray(); } using ApplicationEngine engine = ApplicationEngine.Run(script, extraGAS: 20000000L * accounts.Length); @@ -246,7 +246,7 @@ public Transaction MakeTransaction(TransferOutput[] outputs, UInt160 from = null foreach (UInt160 account in accounts) using (ScriptBuilder sb2 = new ScriptBuilder()) { - sb2.EmitAppCall(assetId, "balanceOf", account); + sb2.EmitAppCall(assetId, ContractParameterType.Integer, "balanceOf", account); using (ApplicationEngine engine = ApplicationEngine.Run(sb2.ToArray(), snapshot, testMode: true)) { if (engine.State.HasFlag(VMState.FAULT)) @@ -265,7 +265,7 @@ public Transaction MakeTransaction(TransferOutput[] outputs, UInt160 from = null cosignerList.UnionWith(balances_used.Select(p => p.Account)); foreach (var (account, value) in balances_used) { - sb.EmitAppCall(output.AssetId, "transfer", account, output.ScriptHash, value); + sb.EmitAppCall(output.AssetId, ContractParameterType.Boolean, "transfer", account, output.ScriptHash, value); sb.Emit(OpCode.ASSERT); } } diff --git a/src/neo/neo.csproj b/src/neo/neo.csproj index ae25d748cb..978c6af877 100644 --- a/src/neo/neo.csproj +++ b/src/neo/neo.csproj @@ -27,7 +27,7 @@ - + diff --git a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index 7e025ad4cd..169aba50d2 100644 --- a/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -158,8 +158,8 @@ public void FeeIsMultiSigContract() var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); Assert.AreEqual(2000810, verificationGas); - Assert.AreEqual(367000, sizeGas); - Assert.AreEqual(2367810, tx.NetworkFee); + Assert.AreEqual(368000, sizeGas); + Assert.AreEqual(2368810, tx.NetworkFee); } } @@ -200,7 +200,7 @@ public void FeeIsSignatureContractDetailed() Assert.IsNull(tx.Witnesses); // check pre-computed network fee (already guessing signature sizes) - tx.NetworkFee.Should().Be(1264390); + tx.NetworkFee.Should().Be(1265390); // ---- // Sign @@ -242,7 +242,7 @@ public void FeeIsSignatureContractDetailed() // ------------------ // check tx_size cost // ------------------ - Assert.AreEqual(264, tx.Size); + Assert.AreEqual(265, tx.Size); // will verify tx size, step by step @@ -256,18 +256,18 @@ public void FeeIsSignatureContractDetailed() // Note that Data size and Usage size are different (because of first byte on GetVarSize()) Assert.AreEqual(22, tx.Cosigners.Values.First().Size); // Part III - Assert.AreEqual(86, tx.Script.GetVarSize()); + Assert.AreEqual(87, tx.Script.GetVarSize()); // Part IV Assert.AreEqual(110, tx.Witnesses.GetVarSize()); // I + II + III + IV - Assert.AreEqual(45 + 23 + 86 + 110, tx.Size); + Assert.AreEqual(45 + 23 + 87 + 110, tx.Size); Assert.AreEqual(1000, NativeContract.Policy.GetFeePerByte(snapshot)); var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); - Assert.AreEqual(264000, sizeGas); + Assert.AreEqual(265000, sizeGas); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1264390, verificationGas + sizeGas); + Assert.AreEqual(1265390, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -302,7 +302,7 @@ public void FeeIsSignatureContract_TestScope_Global() { // self-transfer of 1e-8 GAS System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value; - sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value); + sb.EmitAppCall(NativeContract.GAS.Hash, ContractParameterType.Boolean, "transfer", acc.ScriptHash, acc.ScriptHash, value); sb.Emit(OpCode.ASSERT); script = sb.ToArray(); } @@ -353,7 +353,7 @@ public void FeeIsSignatureContract_TestScope_Global() // get sizeGas var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1264390, verificationGas + sizeGas); + Assert.AreEqual(1265390, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -388,7 +388,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() { // self-transfer of 1e-8 GAS System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value; - sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value); + sb.EmitAppCall(NativeContract.GAS.Hash, ContractParameterType.Boolean, "transfer", acc.ScriptHash, acc.ScriptHash, value); sb.Emit(OpCode.ASSERT); script = sb.ToArray(); } @@ -440,7 +440,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS() // get sizeGas var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1285390, verificationGas + sizeGas); + Assert.AreEqual(1286390, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -475,7 +475,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() { // self-transfer of 1e-8 GAS System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value; - sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value); + sb.EmitAppCall(NativeContract.GAS.Hash, ContractParameterType.Boolean, "transfer", acc.ScriptHash, acc.ScriptHash, value); sb.Emit(OpCode.ASSERT); script = sb.ToArray(); } @@ -530,7 +530,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS() // get sizeGas var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1285390, verificationGas + sizeGas); + Assert.AreEqual(1286390, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -563,7 +563,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT() { // self-transfer of 1e-8 GAS System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value; - sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value); + sb.EmitAppCall(NativeContract.GAS.Hash, ContractParameterType.Boolean, "transfer", acc.ScriptHash, acc.ScriptHash, value); sb.Emit(OpCode.ASSERT); script = sb.ToArray(); } @@ -615,7 +615,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() { // self-transfer of 1e-8 GAS System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value; - sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value); + sb.EmitAppCall(NativeContract.GAS.Hash, ContractParameterType.Boolean, "transfer", acc.ScriptHash, acc.ScriptHash, value); sb.Emit(OpCode.ASSERT); script = sb.ToArray(); } @@ -672,7 +672,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS() // get sizeGas var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1305390, verificationGas + sizeGas); + Assert.AreEqual(1306390, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } @@ -705,7 +705,7 @@ public void FeeIsSignatureContract_TestScope_NoScopeFAULT() { // self-transfer of 1e-8 GAS System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value; - sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value); + sb.EmitAppCall(NativeContract.GAS.Hash, ContractParameterType.Boolean, "transfer", acc.ScriptHash, acc.ScriptHash, value); sb.Emit(OpCode.ASSERT); script = sb.ToArray(); } @@ -953,7 +953,7 @@ public void FeeIsSignatureContract_TestScope_Global_Default() { // self-transfer of 1e-8 GAS System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value; - sb.EmitAppCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value); + sb.EmitAppCall(NativeContract.GAS.Hash, ContractParameterType.Boolean, "transfer", acc.ScriptHash, acc.ScriptHash, value); sb.Emit(OpCode.ASSERT); script = sb.ToArray(); } @@ -1003,7 +1003,7 @@ public void FeeIsSignatureContract_TestScope_Global_Default() // get sizeGas var sizeGas = tx.Size * NativeContract.Policy.GetFeePerByte(snapshot); // final check on sum: verification_cost + tx_size - Assert.AreEqual(1264390, verificationGas + sizeGas); + Assert.AreEqual(1265390, verificationGas + sizeGas); // final assert Assert.AreEqual(tx.NetworkFee, verificationGas + sizeGas); } diff --git a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs index 12b025400b..591cca7abe 100644 --- a/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs +++ b/tests/neo.UnitTests/SmartContract/Native/Tokens/UT_NeoToken.cs @@ -448,7 +448,7 @@ public void TestVote() })); } - sb.EmitAppCall(NativeContract.NEO.Hash, "transfer", from, UInt160.Zero, amount); + sb.EmitAppCall(NativeContract.NEO.Hash, ContractParameterType.Boolean, "transfer", from, UInt160.Zero, amount); engine.LoadScript(sb.ToArray()); engine.Execute(); var result = engine.ResultStack.Peek(); diff --git a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs index 399f063ec7..dd622e6f33 100644 --- a/tests/neo.UnitTests/SmartContract/UT_InteropService.cs +++ b/tests/neo.UnitTests/SmartContract/UT_InteropService.cs @@ -88,7 +88,7 @@ public void Runtime_GetNotifications_Test() // Call script - script.EmitAppCall(scriptHash2, "test", 2, 1); + script.EmitAppCall(scriptHash2, ContractParameterType.Any, "test", 2, 1); // Drop return @@ -138,7 +138,7 @@ public void Runtime_GetNotifications_Test() // Call script - script.EmitAppCall(scriptHash2, "test", 2, 1); + script.EmitAppCall(scriptHash2, ContractParameterType.Any, "test", 2, 1); // Drop return @@ -230,7 +230,7 @@ public void TestExecutionEngine_GetCallingScriptHash() engine.Snapshot.Contracts.Add(contract.ScriptHash, contract); using ScriptBuilder scriptB = new ScriptBuilder(); - scriptB.EmitAppCall(contract.ScriptHash, "test", 0, 1); + scriptB.EmitAppCall(contract.ScriptHash, ContractParameterType.Any, "test", 0, 1); engine.LoadScript(scriptB.ToArray()); Assert.AreEqual(VMState.HALT, engine.Execute()); @@ -609,17 +609,17 @@ public void TestContract_Call() var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true); engine.LoadScript(new byte[] { 0x01 }); - engine.CallContract(state.ScriptHash, method, args); + engine.CallContract(state.ScriptHash, ContractParameterType.Any, method, args); engine.CurrentContext.EvaluationStack.Pop().Should().Be(args[0]); engine.CurrentContext.EvaluationStack.Pop().Should().Be(args[1]); state.Manifest.Permissions[0].Methods = WildcardContainer.Create("a"); - Assert.ThrowsException(() => engine.CallContract(state.ScriptHash, method, args)); + Assert.ThrowsException(() => engine.CallContract(state.ScriptHash, ContractParameterType.Any, method, args)); state.Manifest.Permissions[0].Methods = WildcardContainer.CreateWildcard(); - engine.CallContract(state.ScriptHash, method, args); + engine.CallContract(state.ScriptHash, ContractParameterType.Any, method, args); - Assert.ThrowsException(() => engine.CallContract(UInt160.Zero, method, args)); + Assert.ThrowsException(() => engine.CallContract(UInt160.Zero, ContractParameterType.Any, method, args)); } [TestMethod] @@ -639,15 +639,15 @@ public void TestContract_CallEx() var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true); engine.LoadScript(new byte[] { 0x01 }); - engine.CallContractEx(state.ScriptHash, method, args, CallFlags.All); + engine.CallContractEx(state.ScriptHash, ContractParameterType.Any, method, args, CallFlags.All); engine.CurrentContext.EvaluationStack.Pop().Should().Be(args[0]); engine.CurrentContext.EvaluationStack.Pop().Should().Be(args[1]); // Contract doesn't exists - Assert.ThrowsException(() => engine.CallContractEx(UInt160.Zero, method, args, CallFlags.All)); + Assert.ThrowsException(() => engine.CallContractEx(UInt160.Zero, ContractParameterType.Any, method, args, CallFlags.All)); // Call with rights - engine.CallContractEx(state.ScriptHash, method, args, flags); + engine.CallContractEx(state.ScriptHash, ContractParameterType.Any, method, args, flags); engine.CurrentContext.EvaluationStack.Pop().Should().Be(args[0]); engine.CurrentContext.EvaluationStack.Pop().Should().Be(args[1]); } diff --git a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs index 848079aef3..e15647a635 100644 --- a/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs +++ b/tests/neo.UnitTests/SmartContract/UT_Syscalls.cs @@ -351,10 +351,10 @@ public void System_Runtime_GetInvocationCounter() using (var script = new ScriptBuilder()) { - script.EmitAppCall(contractA.ScriptHash, "dummyMain", 0, 1); - script.EmitAppCall(contractB.ScriptHash, "dummyMain", 0, 1); - script.EmitAppCall(contractB.ScriptHash, "dummyMain", 0, 1); - script.EmitAppCall(contractC.ScriptHash, "dummyMain", 0, 1); + script.EmitAppCall(contractA.ScriptHash, ContractParameterType.Any, "dummyMain", 0, 1); + script.EmitAppCall(contractB.ScriptHash, ContractParameterType.Any, "dummyMain", 0, 1); + script.EmitAppCall(contractB.ScriptHash, ContractParameterType.Any, "dummyMain", 0, 1); + script.EmitAppCall(contractC.ScriptHash, ContractParameterType.Any, "dummyMain", 0, 1); // Execute diff --git a/tests/neo.UnitTests/VM/UT_Helper.cs b/tests/neo.UnitTests/VM/UT_Helper.cs index 4c89fe09a5..e63fb9dd44 100644 --- a/tests/neo.UnitTests/VM/UT_Helper.cs +++ b/tests/neo.UnitTests/VM/UT_Helper.cs @@ -52,19 +52,20 @@ public void TestEmitAppCall1() { //format:(byte)0x10+(byte)OpCode.NEWARRAY+(string)operation+(Uint160)scriptHash+(uint)InteropService.System_Contract_Call ScriptBuilder sb = new ScriptBuilder(); - sb.EmitAppCall(UInt160.Zero, "AAAAA"); - byte[] tempArray = new byte[36]; + sb.EmitAppCall(UInt160.Zero, ContractParameterType.Any, "AAAAA"); + byte[] tempArray = new byte[37]; tempArray[0] = (byte)OpCode.PUSH0; tempArray[1] = (byte)OpCode.NEWARRAY; tempArray[2] = (byte)OpCode.PUSHDATA1; tempArray[3] = 5;//operation.Length Array.Copy(Encoding.UTF8.GetBytes("AAAAA"), 0, tempArray, 4, 5);//operation.data - tempArray[9] = (byte)OpCode.PUSHDATA1; - tempArray[10] = 0x14;//scriptHash.Length - Array.Copy(UInt160.Zero.ToArray(), 0, tempArray, 11, 20);//operation.data + tempArray[9] = (byte)OpCode.PUSH0; + tempArray[10] = (byte)OpCode.PUSHDATA1; + tempArray[11] = 0x14;//scriptHash.Length + Array.Copy(UInt160.Zero.ToArray(), 0, tempArray, 12, 20);//operation.data uint api = ApplicationEngine.System_Contract_Call; - tempArray[31] = (byte)OpCode.SYSCALL; - Array.Copy(BitConverter.GetBytes(api), 0, tempArray, 32, 4);//api.data + tempArray[32] = (byte)OpCode.SYSCALL; + Array.Copy(BitConverter.GetBytes(api), 0, tempArray, 33, 4);//api.data CollectionAssert.AreEqual(tempArray, sb.ToArray()); } @@ -73,20 +74,21 @@ public void TestEmitAppCall2() { //format:(ContractParameter[])ContractParameter+(byte)OpCode.PACK+(string)operation+(Uint160)scriptHash+(uint)InteropService.System_Contract_Call ScriptBuilder sb = new ScriptBuilder(); - sb.EmitAppCall(UInt160.Zero, "AAAAA", new ContractParameter[] { new ContractParameter(ContractParameterType.Integer) }); - byte[] tempArray = new byte[37]; + sb.EmitAppCall(UInt160.Zero, ContractParameterType.Any, "AAAAA", new ContractParameter[] { new ContractParameter(ContractParameterType.Integer) }); + byte[] tempArray = new byte[38]; tempArray[0] = (byte)OpCode.PUSH0; tempArray[1] = (byte)OpCode.PUSH1; tempArray[2] = (byte)OpCode.PACK; tempArray[3] = (byte)OpCode.PUSHDATA1; tempArray[4] = 0x05;//operation.Length Array.Copy(Encoding.UTF8.GetBytes("AAAAA"), 0, tempArray, 5, 5);//operation.data - tempArray[10] = (byte)OpCode.PUSHDATA1; - tempArray[11] = 0x14;//scriptHash.Length - Array.Copy(UInt160.Zero.ToArray(), 0, tempArray, 12, 20);//operation.data + tempArray[10] = (byte)OpCode.PUSH0; + tempArray[11] = (byte)OpCode.PUSHDATA1; + tempArray[12] = 0x14;//scriptHash.Length + Array.Copy(UInt160.Zero.ToArray(), 0, tempArray, 13, 20);//operation.data uint api = ApplicationEngine.System_Contract_Call; - tempArray[32] = (byte)OpCode.SYSCALL; - Array.Copy(BitConverter.GetBytes(api), 0, tempArray, 33, 4);//api.data + tempArray[33] = (byte)OpCode.SYSCALL; + Array.Copy(BitConverter.GetBytes(api), 0, tempArray, 34, 4);//api.data CollectionAssert.AreEqual(tempArray, sb.ToArray()); } @@ -95,29 +97,30 @@ public void TestEmitAppCall3() { //format:(object[])args+(byte)OpCode.PACK+(string)operation+(Uint160)scriptHash+(uint)InteropService.System_Contract_Call ScriptBuilder sb = new ScriptBuilder(); - sb.EmitAppCall(UInt160.Zero, "AAAAA", true); - byte[] tempArray = new byte[37]; + sb.EmitAppCall(UInt160.Zero, ContractParameterType.Any, "AAAAA", true); + byte[] tempArray = new byte[38]; tempArray[0] = (byte)OpCode.PUSH1;//arg tempArray[1] = (byte)OpCode.PUSH1;//args.Length tempArray[2] = (byte)OpCode.PACK; tempArray[3] = (byte)OpCode.PUSHDATA1; tempArray[4] = 0x05;//operation.Length Array.Copy(Encoding.UTF8.GetBytes("AAAAA"), 0, tempArray, 5, 5);//operation.data - tempArray[10] = (byte)OpCode.PUSHDATA1; - tempArray[11] = 0x14;//scriptHash.Length - Array.Copy(UInt160.Zero.ToArray(), 0, tempArray, 12, 20);//operation.data + tempArray[10] = (byte)OpCode.PUSH0; + tempArray[11] = (byte)OpCode.PUSHDATA1; + tempArray[12] = 0x14;//scriptHash.Length + Array.Copy(UInt160.Zero.ToArray(), 0, tempArray, 13, 20);//operation.data uint api = ApplicationEngine.System_Contract_Call; - tempArray[32] = (byte)OpCode.SYSCALL; - Array.Copy(BitConverter.GetBytes(api), 0, tempArray, 33, 4);//api.data + tempArray[33] = (byte)OpCode.SYSCALL; + Array.Copy(BitConverter.GetBytes(api), 0, tempArray, 34, 4);//api.data CollectionAssert.AreEqual(tempArray, sb.ToArray()); } [TestMethod] public void TestMakeScript() { - byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero); + byte[] testScript = NativeContract.GAS.Hash.MakeScript(ContractParameterType.Integer, "balanceOf", UInt160.Zero); - Assert.AreEqual("0c14000000000000000000000000000000000000000011c00c0962616c616e63654f660c14bcaf41d684c7d4ad6ee0d99da9707b9d1f0c8e6641627d5b52", + Assert.AreEqual("0c14000000000000000000000000000000000000000011c00c0962616c616e63654f6600110c14bcaf41d684c7d4ad6ee0d99da9707b9d1f0c8e6641627d5b52", testScript.ToHexString()); } diff --git a/tests/neo.UnitTests/Wallets/SQLite/UT_VerificationContract.cs b/tests/neo.UnitTests/Wallets/SQLite/UT_VerificationContract.cs index 19eaa434dc..75d2ef7a5d 100644 --- a/tests/neo.UnitTests/Wallets/SQLite/UT_VerificationContract.cs +++ b/tests/neo.UnitTests/Wallets/SQLite/UT_VerificationContract.cs @@ -122,7 +122,7 @@ public void TestSerialize() byte[] script = Neo.SmartContract.Contract.CreateSignatureRedeemScript(key.PublicKey); byte[] result = new byte[64]; result[20] = 0x01; - result[21] = 0x00; + result[21] = (byte)ContractParameterType.Signature; result[22] = 0x29; Array.Copy(script, 0, result, 23, 41); CollectionAssert.AreEqual(result, byteArray);