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