/// <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); }