CityOfZion / neo-debugger-tools

A set of tools to develop NEO smart contracts
MIT License
24 stars 20 forks source link

I can not use "CheckWitness" in the unit test of SmartContract. #185

Open skashitam opened 5 years ago

skashitam commented 5 years ago

I can not use "CheckWitness" in the unit test of SmartContract.

If you set CheckWitnessMode of DebugParams to Always True, unit test will work normally.

In DebugParams PrivateKey, I set the WIF that I want to sign Transaction.

Is the setting method of PrivateKey compared by CheckWitness wrong?

lock9 commented 5 years ago

Hello @skashitam, It is supposed to work, could you show me the code you are using?

skashitam commented 5 years ago

Hello @lock9 I want to test for "Transfer".

public static bool Transfer(byte[] from, byte[] to, BigInteger value)
        {
            if (from.Length != 20 || to.Length != 20)
            {
                Runtime.Log("Transfer() (from|to).Length != 20");
                return false;
            }

            if (value < 0)
            {
                Runtime.Log("Transfer() invalid transfer value must be >= 0");
                throw new Exception();
            }

            BigInteger fromBalance = BalanceOf(Storage.CurrentContext, from);
            if (fromBalance < value)
            {
                Runtime.Log("Transfer() fromBalance < transferValue");
                return false;
            }

            if (value == 0 || from == to)
            {
                // don't accept a meaningless value
                Runtime.Log("Transfer() empty transfer amount or from==to");
                Transferred(from, to, value);
                return true;
            }

            if (!Runtime.CheckWitness(from))
            {
                Runtime.Log("Transfer() CheckWitness failed");
                return false;
            }

            var newFromValue = BalanceOf(Storage.CurrentContext, from) - value;
            var newToValue = BalanceOf(Storage.CurrentContext, to) + value;

            Helpers.SetBalanceOf(Storage.CurrentContext, from, newFromValue);
            Helpers.SetBalanceOf(Storage.CurrentContext, to, newToValue);

            Transferred(from, to, value);
            return true;
        }

test code result3 is false if "WitnessMode" is default.

[Test]
        public void TransferTest()
        {
            _debugManager.Blockchain.Reset();

            //mint for transfer test
            _debugManager.SetDebugParameters(CreateDebugParam(
                    "mint",
                    _debugManager.Emulator.currentAccount.keys.WIF,
                    new object[]
                    {
                        "0x" + _debugManager.Emulator.currentAccount.keys.address.ToScriptHash().ByteToHex(),
                        123
                    }
                ));
            _debugManager.Run();

            var output1 = _debugManager.Emulator.GetOutput();
            var result1 = output1.GetBoolean();
            if (result1 != true)
            {
                Assert.Fail("mint is failed.");
            }

            //confirm success to mint
            _debugManager.SetDebugParameters(CreateDebugParam(
                    "balanceOf",
                    _debugManager.Emulator.currentAccount.keys.WIF,
                    new object[]
                    {
                        "0x" + _debugManager.Emulator.currentAccount.keys.address.ToScriptHash().ByteToHex()
                    }
                ));
            _debugManager.Run();

            var output2 = _debugManager.Emulator.GetOutput();
            var result2 = output2.GetBigInteger();
            if(result2 != 123)
            {
                Assert.Fail("after mint balance is not valid.");
            }

            //transfer test
            _debugManager.SetDebugParameters(CreateDebugParam(
                    "transfer",
                    _debugManager.Emulator.currentAccount.keys.WIF,
                    new object[]
                    {
                        "0x" + _debugManager.Emulator.currentAccount.keys.address.ToScriptHash().ByteToHex(),
                        "0x" + "AK3KpVMsb5Bd1BgmrhRw3AXcvxDW3hoyBr".ToScriptHash().ByteToHex(),
                        100
                    }
                ));
            _debugManager.Run();

            var output3 = _debugManager.Emulator.GetOutput();
            var result3 = output3.GetBoolean();
            if(result3 != true)
            {
                Assert.Fail("transfer is failed.");
            }

            //confirm success to transfer
            _debugManager.SetDebugParameters(CreateDebugParam(
                    "balanceOf",
                    _debugManager.Emulator.currentAccount.keys.WIF,
                    new object[]
                    {
                        "0x" + _debugManager.Emulator.currentAccount.keys.address.ToScriptHash().ByteToHex()
                    }
                ));
            _debugManager.Run();

            var output4 = _debugManager.Emulator.GetOutput();
            var result4 = output4.GetBigInteger();
            if(result4 != 23)
            {
                Assert.Fail("after transfer from balance is not valid.");
            }

            _debugManager.SetDebugParameters(CreateDebugParam(
                    "balanceOf",
                    _debugManager.Emulator.currentAccount.keys.WIF,
                    new object[]
                    {
                        "0x" + "AK3KpVMsb5Bd1BgmrhRw3AXcvxDW3hoyBr".ToScriptHash().ByteToHex(),
                    }
                ));
            _debugManager.Run();

            var output5 = _debugManager.Emulator.GetOutput();
            var result5 = output5.GetBigInteger();
            if (result5 != 100)
            {
                Assert.Fail("after transfer to balance is not valid.");
            }
        }
private DebugParameters CreateDebugParam(string method, string privateKey, object[] param)
        {
            var inputs = DataNode.CreateArray();
            inputs.AddValue(method);

            if(param != null && param.Length > 0)
            {
                var _param = DataNode.CreateArray();
                foreach(var o in param)
                {
                    _param.AddValue(o);
                }
                inputs.AddNode(_param);
            }
            else
            {
                inputs.AddValue(null);
            }

            var debugParam = new DebugParameters()
            {
                ArgList = inputs,
                PrivateKey = privateKey,
                WitnessMode = CheckWitnessMode.AlwaysTrue//test successed if "AlwaysTrue"
            };

            return debugParam;
        }
lock9 commented 5 years ago

Hello, What branch are you using?