Exemplo n.º 1
0
        public byte[] Encode(AbiEncodingStyle encodingStyle, AbiSignature signature, params object[] arguments)
        {
            bool packed = (encodingStyle & AbiEncodingStyle.Packed) == AbiEncodingStyle.Packed;

            if (arguments.Length != signature.Types.Length)
            {
                throw new AbiException(
                          $"Insufficient parameters for {signature.Name}. Expected {signature.Types.Length} arguments but got {arguments.Length}");
            }

            List <byte[]> dynamicParts  = new();
            List <byte[]> headerParts   = new();
            BigInteger    currentOffset = arguments.Length * AbiType.UInt256.LengthInBytes;

            for (int i = 0; i < arguments.Length; i++)
            {
                AbiType type = signature.Types[i];
                if (type.IsDynamic)
                {
                    headerParts.Add(AbiType.UInt256.Encode(currentOffset, packed));
                    byte[] encoded = type.Encode(arguments[i], packed);
                    currentOffset += encoded.Length;
                    dynamicParts.Add(encoded);
                }
                else
                {
                    headerParts.Add(type.Encode(arguments[i], packed));
                }
            }

            bool includeSig = encodingStyle == AbiEncodingStyle.IncludeSignature;
            int  sigOffset  = includeSig ? 1 : 0;

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

            if (includeSig)
            {
                encodedParts[0] = signature.Address;
            }

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

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

            return(Bytes.Concat(encodedParts));
        }
Exemplo n.º 2
0
        public byte[] Encode(AbiEncodingStyle encodingStyle, AbiSignature signature, params object[] arguments)
        {
            bool packed = (encodingStyle & AbiEncodingStyle.Packed) == AbiEncodingStyle.Packed;

            List <byte[]> dynamicParts  = new List <byte[]>();
            List <byte[]> headerParts   = new List <byte[]>();
            BigInteger    currentOffset = arguments.Length * AbiType.UInt256.LengthInBytes;

            for (int i = 0; i < arguments.Length; i++)
            {
                AbiType type = signature.Types[i];
                if (type.IsDynamic)
                {
                    headerParts.Add(AbiType.UInt256.Encode(currentOffset, packed));
                    byte[] encoded = type.Encode(arguments[i], packed);
                    currentOffset += encoded.Length;
                    dynamicParts.Add(encoded);
                }
                else
                {
                    headerParts.Add(type.Encode(arguments[i], packed));
                }
            }

            bool includeSig = encodingStyle == AbiEncodingStyle.IncludeSignature;
            int  sigOffset  = includeSig ? 1 : 0;

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

            if (includeSig)
            {
                encodedParts[0] = ComputeAddress(signature);
            }

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

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

            return(Bytes.Concat(encodedParts));
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        public byte[] Encode(AbiSignature signature, params object[] arguments)
        {
            List <byte[]> dynamicParts  = new List <byte[]>();
            List <byte[]> headerParts   = new List <byte[]>();
            BigInteger    currentOffset = arguments.Length * AbiType.UInt.LengthInBytes;

            for (int i = 0; i < arguments.Length; i++)
            {
                AbiType type = signature.Types[i];
                if (type.IsDynamic)
                {
                    headerParts.Add(AbiType.UInt.Encode(currentOffset));
                    byte[] encoded = type.Encode(arguments[i]);
                    currentOffset += encoded.Length;
                    dynamicParts.Add(encoded);
                }
                else
                {
                    headerParts.Add(type.Encode(arguments[i]));
                }
            }

            byte[][] encodedParts = new byte[1 + headerParts.Count + dynamicParts.Count][];
            encodedParts[0] = ComputeAddress(signature);
            for (int i = 0; i < headerParts.Count; i++)
            {
                encodedParts[1 + i] = headerParts[i];
            }

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

            return(Bytes.Concat(encodedParts));
        }
Exemplo n.º 5
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++] = UInt.Encode((BigInteger)input.Length, packed);
                foreach (object o in input)
                {
                    encodedItems[i++] = _elementType.Encode(o, packed);
                }

                return(Bytes.Concat(encodedItems));
            }

            throw new AbiException(AbiEncodingExceptionMessage);
        }
Exemplo n.º 6
0
        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);
        }