pub fn encodeWithBytes(
allocator: std.mem.Allocator,
addr: primitives.Address,
bytes_data: []const u8,
) !primitives.CallData {
var data = std.ArrayList(u8){};
defer data.deinit(allocator);
// Selector (assumed computed)
const selector = [_]u8{ 0x12, 0x34, 0x56, 0x78 };
try data.appendSlice(allocator, &selector);
// Address (static, 32 bytes)
var addr_buf: [32]u8 = [_]u8{0} ** 32;
@memcpy(addr_buf[12..32], &addr.bytes);
try data.appendSlice(allocator, &addr_buf);
// Offset to dynamic data (32 bytes after address)
const offset: u256 = 32;
var offset_buf: [32]u8 = undefined;
std.mem.writeInt(u256, &offset_buf, offset, .big);
try data.appendSlice(allocator, &offset_buf);
// Dynamic data length
const length: u256 = bytes_data.len;
var length_buf: [32]u8 = undefined;
std.mem.writeInt(u256, &length_buf, length, .big);
try data.appendSlice(allocator, &length_buf);
// Dynamic data (right-padded)
try data.appendSlice(allocator, bytes_data);
const padding = (32 - (bytes_data.len % 32)) % 32;
if (padding > 0) {
try data.appendNTimes(allocator, 0, padding);
}
return primitives.CallData{
.data = try data.toOwnedSlice(allocator),
};
}