Пример #1
0
        public T DecodeSimpleTypeOutput <T>(Parameter outputParameter, string output)
        {
            if (output == "0x")
            {
                return(default(T));
            }

            if (outputParameter != null)
            {
                var parmeterOutput = new ParameterOutput()
                {
                    DecodedType = typeof(T),
                    Parameter   = outputParameter
                };

                var results = DecodeOutput(output, parmeterOutput);

                if (results.Any())
                {
                    return((T)results[0].Result);
                }
            }

            return(default(T));
        }
        public List <ParameterOutput> DecodeOutput(byte[] outputBytes, params ParameterOutput[] outputParameters)
        {
            var currentIndex = 0;

            // discard initial offset
            if (outputParameters.Count() > 1 && outputParameters.Any(oP => oP.Parameter.ABIType.Name == "tuple[]"))
            {
                // remove the starting 0x20
                currentIndex = 32;
            }

            foreach (var outputParam in outputParameters)
            {
                var param = outputParam.Parameter;
                if (param.ABIType.IsDynamic())
                {
                    outputParam.DataIndexStart =
                        EncoderDecoderHelpers.GetNumberOfBytes(outputBytes.Skip(currentIndex).ToArray());
                    // should only happen on tuples, as we look for their location
                    if (currentIndex != 0 && (outputParam.Parameter.ABIType.Name == "tuple" || outputParam.Parameter.ABIType.Name == "tuple[]"))
                    {
                        outputParam.DataIndexStart = outputParam.DataIndexStart + 32; //including its current index 32 bytes
                    }
                    currentIndex = currentIndex + 32;
                }
                else
                {
                    var bytes = outputBytes.Skip(currentIndex).Take(param.ABIType.FixedSize).ToArray();
                    outputParam.Result = param.ABIType.Decode(bytes, outputParam.Parameter.DecodedType);

                    currentIndex = currentIndex + param.ABIType.FixedSize;
                }
            }

            ParameterOutput currentDataItem = null;

            foreach (
                var nextDataItem in outputParameters.Where(outputParam => outputParam.Parameter.ABIType.IsDynamic()))
            {
                if (currentDataItem != null)
                {
                    var bytes =
                        outputBytes.Skip(currentDataItem.DataIndexStart).Take(nextDataItem.DataIndexStart - currentDataItem.DataIndexStart).ToArray();
                    currentDataItem.Result = currentDataItem.Parameter.ABIType.Decode(bytes, currentDataItem.Parameter.DecodedType);
                }
                currentDataItem = nextDataItem;
            }

            if (currentDataItem != null)
            {
                var bytes = outputBytes.Skip(currentDataItem.DataIndexStart).ToArray();
                currentDataItem.Result = currentDataItem.Parameter.ABIType.Decode(bytes, currentDataItem.Parameter.DecodedType);
            }
            return(outputParameters.ToList());
        }
Пример #3
0
        public List <ParameterOutput> DecodeOutput(byte[] outputBytes, params ParameterOutput[] outputParameters)
        {
            var currentIndex = 0;

            Array.Sort(outputParameters, (x, y) => x.Parameter.Order.CompareTo(y.Parameter.Order));

            foreach (var outputParam in outputParameters)
            {
                var param = outputParam.Parameter;
                if (param.ABIType.IsDynamic())
                {
                    outputParam.DataIndexStart =
                        EncoderDecoderHelpers.GetNumberOfBytes(outputBytes.Skip(currentIndex).ToArray());
                    currentIndex = currentIndex + 32;
                }
                else
                {
                    var bytes = outputBytes.Skip(currentIndex).Take(param.ABIType.FixedSize).ToArray();
                    outputParam.Result = param.ABIType.Decode(bytes, outputParam.Parameter.DecodedType);

                    currentIndex = currentIndex + param.ABIType.FixedSize;
                }
            }

            ParameterOutput currentDataItem = null;

            foreach (
                var nextDataItem in outputParameters.Where(outputParam => outputParam.Parameter.ABIType.IsDynamic()))
            {
                if (currentDataItem != null)
                {
                    var bytes =
                        outputBytes.Skip(currentDataItem.DataIndexStart).Take(nextDataItem.DataIndexStart - currentDataItem.DataIndexStart).ToArray();
                    currentDataItem.Result = currentDataItem.Parameter.ABIType.Decode(bytes, currentDataItem.Parameter.DecodedType);
                }
                currentDataItem = nextDataItem;
            }

            if (currentDataItem != null)
            {
                var bytes = outputBytes.Skip(currentDataItem.DataIndexStart).ToArray();
                currentDataItem.Result = currentDataItem.Parameter.ABIType.Decode(bytes, currentDataItem.Parameter.DecodedType);
            }
            return(outputParameters.ToList());
        }
        public List <ParameterOutput> DecodeDefaultTopics(Parameter[] inputParameters, object[] topics, string data)
        {
            var parameterOutputs = new List <ParameterOutput>();

            var indexedParameters = inputParameters.Where(x => x.Indexed == true).OrderBy(x => x.Order).ToArray();
            var dataParameters    = inputParameters.Where(x => x.Indexed == false).OrderBy(x => x.Order).ToArray();

            // Take one off topics count to skip signature
            var topicCount             = (topics.Length - 1);
            var indexedPropertiesCount = indexedParameters.Length;

            if (indexedPropertiesCount != (topicCount))
            {
                throw new Exception($"Number of indexes don't match the number of topics. Indexed Properties {indexedPropertiesCount}, Topics : {topicCount}");
            }

            var topicNumber = 0;

            foreach (var topic in topics)
            {
                //skip the first one as it is the signature
                if (topicNumber > 0)
                {
                    var parameter = indexedParameters[topicNumber - 1];

                    //skip dynamic types as the topic value is the sha3 keccak
                    if (!parameter.ABIType.IsDynamic())
                    {
                        parameterOutputs.Add(DecodeDefaultData(topic.ToString(), parameter).FirstOrDefault());
                    }
                    else
                    {
                        var parameterOutput = new ParameterOutput()
                        {
                            Parameter = parameter, Result = topic.ToString()
                        };
                        parameterOutputs.Add(parameterOutput);
                    }
                }
                topicNumber = topicNumber + 1;
            }
            parameterOutputs.AddRange(DecodeDefaultData(data, dataParameters.ToArray()));
            return(parameterOutputs);
        }
Пример #5
0
        public T DecodeSimpleTypeOutput <T>(Parameter outputParameter, string output)
        {
            if (output == "0x")
            {
                return(default(T));
            }
            ThrowIfErrorOnOutput(output);
            if (outputParameter != null)
            {
                outputParameter.DecodedType = typeof(T);
                var parmeterOutput = new ParameterOutput
                {
                    Parameter = outputParameter
                };

                if (outputParameter.ABIType is TupleType tupleType)
                {
                    if (typeof(T) == typeof(List <ParameterOutput>))
                    {
                        var results = DecodeOutput(output, parmeterOutput);

                        if (results.Any())
                        {
                            return((T)results[0].Result);
                        }
                    }
                    else
                    {
                        return((T)DecodeAttributes(output.HexToByteArray().Skip(32).ToArray(), typeof(T)));
                    }
                }
                else
                {
                    var results = DecodeOutput(output, parmeterOutput);
                    if (results.Any())
                    {
                        return((T)results[0].Result);
                    }
                }
            }

            return(default(T));
        }
Пример #6
0
        ///<summary>
        /// Decodes the output of a function using either a FunctionOutputAttribute  (T)
        ///  or the parameter casted to the type T, only one outputParameter should be used in this scenario.
        /// </summary>
        ///
        public T DecodeOutput <T>(string output, params Parameter[] outputParameter) where T : new()
        {
            if (output == "0x")
            {
                return(default(T));
            }
            var function = FunctionOutputAttribute.GetAttribute <T>();

            if (function == null)
            {
                if (outputParameter != null)
                {
                    if (outputParameter.Length > 1)
                    {
                        throw new Exception(
                                  "Only one output parameter supported to be decoded this way, use a FunctionOutputAttribute or define each outputparameter");
                    }

                    var parmeterOutput = new ParameterOutput()
                    {
                        DecodedType = typeof(T),
                        Parameter   = outputParameter[0]
                    };

                    var results = DecodeOutput(output, parmeterOutput);

                    if (results.Any())
                    {
                        return((T)results[0].Result);
                    }
                }

                return(default(T));
            }
            else
            {
                return(DecodeOutput <T>(output));
            }
        }