encode method

  1. @override
void encode(
  1. List data,
  2. LengthTrackingByteSink buffer
)
override

Writes data into the buffer.

Implementation

@override
void encode(List data, LengthTrackingByteSink buffer) {
  // Formal definition of the encoding: https://solidity.readthedocs.io/en/develop/abi-spec.html#formal-specification-of-the-encoding
  assert(data.length == types.length);

  // first, encode all non-dynamic values. For each dynamic value we
  // encounter, encode its position instead. Then, encode all the dynamic
  // values.
  var currentDynamicOffset = 0;
  final dynamicHeaderPositions = List.filled(data.length, -1);

  for (var i = 0; i < data.length; i++) {
    final payload = data[i];
    final type = types[i];

    if (type.encodingLength.isDynamic) {
      // just write a bunch of zeroes, we later have to encode the relative
      // offset here.
      dynamicHeaderPositions[i] = buffer.length;
      buffer.add(Uint8List(sizeUnitBytes));

      currentDynamicOffset += sizeUnitBytes;
    } else {
      final lengthBefore = buffer.length;
      type.encode(payload, buffer);

      currentDynamicOffset += buffer.length - lengthBefore;
    }
  }

  // now that the heads are written, write tails for the dynamic values
  for (var i = 0; i < data.length; i++) {
    if (!types[i].encodingLength.isDynamic) continue;

    // replace the 32 zero-bytes with the actual encoded offset
    const UintType().encodeReplace(
      dynamicHeaderPositions[i],
      BigInt.from(currentDynamicOffset),
      buffer,
    );

    final lengthBefore = buffer.length;
    types[i].encode(data[i], buffer);
    currentDynamicOffset += buffer.length - lengthBefore;
  }
}