Skip to content

Instantly share code, notes, and snippets.

@Philogy
Created May 5, 2026 22:39
Show Gist options
  • Select an option

  • Save Philogy/abf2759280b0456743c2c3d132bba528 to your computer and use it in GitHub Desktop.

Select an option

Save Philogy/abf2759280b0456743c2c3d132bba528 to your computer and use it in GitHub Desktop.
(Draft) Event In Plank `std`
import std::utils::{fold, bool_to_uint};
import std::membytes::*;
const Indexed = fn (comptime T: type) type {
return struct {
value: T
};
};
const is_indexed = fn (comptime T: type) bool {
@is_struct(T)
and @field_count(T) == 1
and Indexed(@field_type(T, 0)) == T
};
const as_indexed = fn (comptime T: type, value: T) u256 {
if T == u256 {
value
} else if T == bool {
bool_to_uint(value)
} else if T == membytes {
@evm_keccak256(value.ptr, value.len)
} else {
let _type_not_supported_as_indexed_param: void = true;
}
};
const get_indexed_count = fn (comptime T: type) u256 {
let count_indexed_step = fn (comptime field_idx: u256, total: u256) u256 {
total + bool_to_uint(is_indexed(@field_type(T, field_idx)))
};
fold(u256, @field_count(T), count_indexed_step, 0)
};
const IndexedParams = struct {
_0: u256,
_1: u256,
_2: u256,
};
const collect_indexed = fn (
comptime T: type,
event: T,
comptime indexed_count: u256,
comptime indexed_idx: u256,
comptime field_idx: u256,
params: IndexedParams,
) IndexedParams {
if indexed_idx == indexed_count or field_idx == @field_count(T) {
return params;
}
let FieldT = @field_type(T, field_idx);
if comptime { !is_indexed(FieldT) } {
return collect_indexed(T, event, indexed_count, indexed_idx, field_idx + 1, params);
}
let FieldT = @field_type(FieldT, 0);
let indexed = as_indexed(FieldT, @get_field(event, field_idx).value);
let params = @set_field(params, indexed_idx, indexed);
return collect_indexed(T, event, indexed_count, indexed_idx + 1, field_idx + 1, params);
};
const emit = fn (comptime T: type, event_sig: u256, event: T) void {
if !@is_struct(T) or comptime { is_indexed(T) } {
let _unsupported_event_type: void = true;
}
let indexed_count = comptime { get_indexed_count(T) };
if indexed_count > 3 {
let _unsupported_indexed_field_count: indexed_count = true;
}
let indexed = collect_indexed(T, event, indexed_count, 0, 0, @uninit(IndexedParams));
// TODO: Properly encoded
let encoded = membytes_new(0);
if indexed_count == 0 {
@evm_log1(encoded.ptr, encoded.len, event_sig);
} else if indexed_count == 1 {
@evm_log2(encoded.ptr, encoded.len, event_sig, indexed._0);
} else if indexed_count == 2 {
@evm_log3(encoded.ptr, encoded.len, event_sig, indexed._0, indexed._1);
} else if indexed_count == 3 {
@evm_log4(encoded.ptr, encoded.len, event_sig, indexed._0, indexed._1, indexed._2);
}
};
const Transfer = struct {
from: Indexed(u256),
to: Indexed(u256),
amount: u256
};
init {
let mut a = comptime {
get_indexed_count(struct {})
};
let mut a = comptime {
get_indexed_count(struct {
a: u256,
})
};
let mut a = comptime {
get_indexed_count(struct {
a: u256,
b: Indexed(u256),
c: Indexed(u256),
})
};
let mut a = comptime {
get_indexed_count(struct {
x: Indexed(bool),
b: Indexed(u256),
a: u256,
y: Indexed(u256),
c: Indexed(membytes),
})
};
emit(Transfer, 0xc1c1c1, Transfer {
from: Indexed(u256) { value: 0xaaaa },
to: Indexed(u256) { value: 0xbbbb },
amount: 0xffffffff
});
let encoded = @malloc_uninit(0x20);
@mstore32(encoded, 0xffffffff);
log3(encoded, 0x20, 0xc1c1c1, 0xaaaa, 0xbbbb);
@evm_stop();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment