From 116d5a88460e8bb10b3aba88d950eef3bf036f2c Mon Sep 17 00:00:00 2001 From: Shargon Date: Wed, 17 Feb 2021 08:45:22 +0100 Subject: [PATCH] Add CreateStandardMultisigAccount (#2343) * Add CreateStandardMultisigAccount * plural * dotnet-format * Rename * Use CreateArray() * Fix UT Co-authored-by: Erik Zhang --- .../ApplicationEngine.Contract.cs | 6 +++ src/neo/VM/Helper.cs | 12 +---- .../UT_ApplicationEngine.Contract.cs | 50 +++++++++++++++++++ .../SmartContract/UT_ApplicationEngine.cs | 2 +- 4 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs diff --git a/src/neo/SmartContract/ApplicationEngine.Contract.cs b/src/neo/SmartContract/ApplicationEngine.Contract.cs index f75eb3f188..2ea536c059 100644 --- a/src/neo/SmartContract/ApplicationEngine.Contract.cs +++ b/src/neo/SmartContract/ApplicationEngine.Contract.cs @@ -19,6 +19,7 @@ partial class ApplicationEngine /// Warning: check first that input public key is valid, before creating the script. /// public static readonly InteropDescriptor System_Contract_CreateStandardAccount = Register("System.Contract.CreateStandardAccount", nameof(CreateStandardAccount), 1 << 8, CallFlags.None); + public static readonly InteropDescriptor System_Contract_CreateMultisigAccount = Register("System.Contract.CreateMultisigAccount", nameof(CreateMultisigAccount), 1 << 8, CallFlags.None); public static readonly InteropDescriptor System_Contract_NativeOnPersist = Register("System.Contract.NativeOnPersist", nameof(NativeOnPersist), 0, CallFlags.WriteStates); public static readonly InteropDescriptor System_Contract_NativePostPersist = Register("System.Contract.NativePostPersist", nameof(NativePostPersist), 0, CallFlags.WriteStates); @@ -86,6 +87,11 @@ protected internal UInt160 CreateStandardAccount(ECPoint pubKey) return Contract.CreateSignatureRedeemScript(pubKey).ToScriptHash(); } + protected internal UInt160 CreateMultisigAccount(int m, ECPoint[] pubKeys) + { + return Contract.CreateMultiSigRedeemScript(m, pubKeys).ToScriptHash(); + } + protected internal void NativeOnPersist() { if (Trigger != TriggerType.OnPersist) diff --git a/src/neo/VM/Helper.cs b/src/neo/VM/Helper.cs index 7a6165b397..001e044f8e 100644 --- a/src/neo/VM/Helper.cs +++ b/src/neo/VM/Helper.cs @@ -53,17 +53,7 @@ public static ScriptBuilder EmitDynamicCall(this ScriptBuilder sb, UInt160 scrip public static ScriptBuilder EmitDynamicCall(this ScriptBuilder sb, UInt160 scriptHash, string operation, CallFlags flags, params object[] args) { - if (args.Length == 0) - { - sb.Emit(OpCode.NEWARRAY0); - } - else - { - for (int i = args.Length - 1; i >= 0; i--) - sb.EmitPush(args[i]); - sb.EmitPush(args.Length); - sb.Emit(OpCode.PACK); - } + sb.CreateArray(args); sb.EmitPush(flags); sb.EmitPush(operation); sb.EmitPush(scriptHash); diff --git a/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs new file mode 100644 index 0000000000..939cc282a2 --- /dev/null +++ b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.Contract.cs @@ -0,0 +1,50 @@ +using FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.SmartContract; +using Neo.VM; +using System.Linq; + +namespace Neo.UnitTests.SmartContract +{ + public partial class UT_ApplicationEngine + { + [TestMethod] + public void TestCreateStandardAccount() + { + var settings = ProtocolSettings.Default; + using var engine = ApplicationEngine.Create(TriggerType.Application, null, null, settings: TestBlockchain.TheNeoSystem.Settings, gas: 1100_00000000); + + using var script = new ScriptBuilder(); + script.EmitSysCall(ApplicationEngine.System_Contract_CreateStandardAccount, settings.StandbyCommittee[0].EncodePoint(true)); + engine.LoadScript(script.ToArray()); + + Assert.AreEqual(VMState.HALT, engine.Execute()); + + var result = engine.ResultStack.Pop(); + new UInt160(result.GetSpan()).Should().Be(Contract.CreateSignatureRedeemScript(settings.StandbyCommittee[0]).ToScriptHash()); + } + + [TestMethod] + public void TestCreateStandardMultisigAccount() + { + var settings = ProtocolSettings.Default; + using var engine = ApplicationEngine.Create(TriggerType.Application, null, null, settings: TestBlockchain.TheNeoSystem.Settings, gas: 1100_00000000); + + using var script = new ScriptBuilder(); + script.EmitSysCall(ApplicationEngine.System_Contract_CreateMultisigAccount, new object[] + { + 2, + 3, + settings.StandbyCommittee[0].EncodePoint(true), + settings.StandbyCommittee[1].EncodePoint(true), + settings.StandbyCommittee[2].EncodePoint(true) + }); + engine.LoadScript(script.ToArray()); + + Assert.AreEqual(VMState.HALT, engine.Execute()); + + var result = engine.ResultStack.Pop(); + new UInt160(result.GetSpan()).Should().Be(Contract.CreateMultiSigRedeemScript(2, settings.StandbyCommittee.Take(3).ToArray()).ToScriptHash()); + } + } +} diff --git a/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs index 9b808a907c..66f4f87e64 100644 --- a/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs +++ b/tests/neo.UnitTests/SmartContract/UT_ApplicationEngine.cs @@ -6,7 +6,7 @@ namespace Neo.UnitTests.SmartContract { [TestClass] - public class UT_ApplicationEngine + public partial class UT_ApplicationEngine { private string eventName = null;