Exemple #1
0
        public void TestEmitMap()
        {
            var expected = new Dictionary <BigInteger, BigInteger>()
            {
                { 1, 2 }, { 3, 4 }
            };
            var sb = new ScriptBuilder();

            sb.CreateMap(expected);

            using var engine = ApplicationEngine.Create(TriggerType.Application, null, null);
            engine.LoadScript(sb.ToArray());
            Assert.AreEqual(VMState.HALT, engine.Execute());

            var map = engine.ResultStack.Pop <VM.Types.Map>();
            var dic = map.ToDictionary(u => u.Key, u => u.Value);

            CollectionAssert.AreEqual(expected.Keys, dic.Keys.Select(u => u.GetInteger()).ToArray());
            CollectionAssert.AreEqual(expected.Values, dic.Values.Select(u => u.GetInteger()).ToArray());
        }
Exemple #2
0
        /// <summary>
        /// Emits the opcodes for pushing the specified data onto the stack.
        /// </summary>
        /// <param name="builder">The <see cref="ScriptBuilder"/> to be used.</param>
        /// <param name="parameter">The data to be pushed.</param>
        /// <returns>The same instance as <paramref name="builder"/>.</returns>
        public static ScriptBuilder EmitPush(this ScriptBuilder builder, ContractParameter parameter)
        {
            if (parameter.Value is null)
            {
                builder.Emit(OpCode.PUSHNULL);
            }
            else
            {
                switch (parameter.Type)
                {
                case ContractParameterType.Signature:
                case ContractParameterType.ByteArray:
                    builder.EmitPush((byte[])parameter.Value);
                    break;

                case ContractParameterType.Boolean:
                    builder.EmitPush((bool)parameter.Value);
                    break;

                case ContractParameterType.Integer:
                    if (parameter.Value is BigInteger bi)
                    {
                        builder.EmitPush(bi);
                    }
                    else
                    {
                        builder.EmitPush((BigInteger)typeof(BigInteger).GetConstructor(new[] { parameter.Value.GetType() }).Invoke(new[] { parameter.Value }));
                    }
                    break;

                case ContractParameterType.Hash160:
                    builder.EmitPush((UInt160)parameter.Value);
                    break;

                case ContractParameterType.Hash256:
                    builder.EmitPush((UInt256)parameter.Value);
                    break;

                case ContractParameterType.PublicKey:
                    builder.EmitPush((ECPoint)parameter.Value);
                    break;

                case ContractParameterType.String:
                    builder.EmitPush((string)parameter.Value);
                    break;

                case ContractParameterType.Array:
                {
                    IList <ContractParameter> parameters = (IList <ContractParameter>)parameter.Value;
                    for (int i = parameters.Count - 1; i >= 0; i--)
                    {
                        builder.EmitPush(parameters[i]);
                    }
                    builder.EmitPush(parameters.Count);
                    builder.Emit(OpCode.PACK);
                }
                break;

                case ContractParameterType.Map:
                {
                    var pairs = (IList <KeyValuePair <ContractParameter, ContractParameter> >)parameter.Value;
                    builder.CreateMap(pairs);
                }
                break;

                default:
                    throw new ArgumentException(null, nameof(parameter));
                }
            }
            return(builder);
        }