Beispiel #1
0
        public override byte[] Encode(object?arg, bool packed)
        {
            if (arg is Array input)
            {
                byte[][] encodedItems = EncodeSequence(input.Length, ElementTypes, input.Cast <object?>(), packed, 1);
                encodedItems[0] = UInt256.Encode((BigInteger)input.Length, packed);
                return(Bytes.Concat(encodedItems));
            }

            throw new AbiException(AbiEncodingExceptionMessage);
        }
Beispiel #2
0
        public override byte[] Encode(object arg, bool packed)
        {
            if (arg is BigRational input)
            {
                if (_denominator != input.Denominator)
                {
                    throw new AbiException(AbiEncodingExceptionMessage);
                }

                return(UInt256.Encode(input.Numerator, packed));
            }

            throw new AbiException(AbiEncodingExceptionMessage);
        }
Beispiel #3
0
        public override byte[] Encode(object arg, bool packed)
        {
            if (arg is byte[] input)
            {
                int    paddingSize   = (1 + input.Length / PaddingMultiple) * PaddingMultiple;
                byte[] lengthEncoded = UInt256.Encode(new BigInteger(input.Length), packed);
                return(Bytes.Concat(lengthEncoded, packed ? input : input.PadRight(paddingSize)));
            }

            if (arg is string stringInput)
            {
                return(Encode(Encoding.ASCII.GetBytes(stringInput), packed));
            }

            throw new AbiException(AbiEncodingExceptionMessage);
        }
Beispiel #4
0
        public override byte[] Encode(object arg, bool packed)
        {
            if (arg is Array input)
            {
                byte[][] encodedItems = new byte[input.Length + 1][];
                int      i            = 0;
                encodedItems[i++] = UInt256.Encode((BigInteger)input.Length, packed);
                foreach (object o in input)
                {
                    encodedItems[i++] = _elementType.Encode(o, packed);
                }

                return(Bytes.Concat(encodedItems));
            }

            throw new AbiException(AbiEncodingExceptionMessage);
        }
        public override byte[] Encode(object arg, bool packed)
        {
            if (arg is Array input)
            {
                if (input.Length != Length)
                {
                    throw new AbiException(AbiEncodingExceptionMessage);
                }

                if (_elementType.IsDynamic)
                {
                    byte[][]   encodedItems  = new byte[Length * 2 - 1][];
                    BigInteger currentOffset = (Length - 1) * UInt256.LengthInBytes;
                    int        i             = 0;
                    foreach (object o in input)
                    {
                        encodedItems[Length + i - 1] = _elementType.Encode(o, packed);
                        if (i != 0)
                        {
                            encodedItems[i - 1] = UInt256.Encode(currentOffset, packed);
                            currentOffset      += new BigInteger(encodedItems[Length + i - 1].Length);
                        }

                        i++;
                    }

                    return(Bytes.Concat(encodedItems));
                }
                else
                {
                    byte[][] encodedItems = new byte[Length][];
                    int      i            = 0;
                    foreach (object o in input)
                    {
                        encodedItems[i++] = _elementType.Encode(o, packed);
                    }

                    return(Bytes.Concat(encodedItems));
                }
            }

            throw new AbiException(AbiEncodingExceptionMessage);
        }
        internal static byte[][] EncodeSequence(int length, IEnumerable <AbiType> types, IEnumerable <object?> sequence, bool packed, int offset = 0)
        {
            List <byte[]>  dynamicParts = new(length);
            List <byte[]?> headerParts  = new(length);

            using IEnumerator <object?> sequenceEnumerator = sequence.GetEnumerator();
            using IEnumerator <AbiType> typesEnumerator    = types.GetEnumerator();
            for (int i = 0; i < length; i++)
            {
                sequenceEnumerator.MoveNext();
                typesEnumerator.MoveNext();
                object? element = sequenceEnumerator.Current;
                AbiType type    = typesEnumerator.Current;

                byte[] encoded = type.Encode(element, packed);

                // encode each type
                if (type.IsDynamic)
                {
                    // offset placeholder, we cannot calculate offset before calculating all header parts
                    headerParts.Add(null);
                    dynamicParts.Add(encoded);
                }
                else
                {
                    headerParts.Add(encoded);
                }
            }

            // now lets calculate proper offset
            BigInteger currentOffset = 0;

            // offset of header
            for (int i = 0; i < headerParts.Count; i++)
            {
                currentOffset += headerParts[i]?.Length ?? PaddingSize;
            }

            // offset dynamic parts, calculating the actual offset of each part
            int dynamicPartsIndex = 0;

            for (int i = 0; i < headerParts.Count; i++)
            {
                if (headerParts[i] is null)
                {
                    headerParts[i] = UInt256.Encode(currentOffset, packed);
                    currentOffset += dynamicParts[dynamicPartsIndex++].Length;
                }
            }

            byte[][] encodedParts = new byte[offset + headerParts.Count + dynamicParts.Count][];

            for (int i = 0; i < headerParts.Count; i++)
            {
                encodedParts[offset + i] = headerParts[i] !;
            }

            for (int i = 0; i < dynamicParts.Count; i++)
            {
                encodedParts[offset + headerParts.Count + i] = dynamicParts[i];
            }

            return(encodedParts);
        }