diff --git a/fastx_programmability/framework/sources/ID.move b/fastx_programmability/framework/sources/ID.move index 4d8a1d1fecef1..875a5e62a8c55 100644 --- a/fastx_programmability/framework/sources/ID.move +++ b/fastx_programmability/framework/sources/ID.move @@ -65,11 +65,7 @@ module FastX::ID { /// Get the ID for `obj`. Safe because fastX has an extra /// bytecode verifier pass that forces every struct with /// the `key` ability to have a distinguished `ID` field. - //public native fun get_id(obj: &T): &ID; - public fun get_id(_obj: &T): &ID { - // TODO: implement native function for this. - abort(0) - } + public native fun get_id(obj: &T): &ID; public native fun bytes_to_address(bytes: vector): address; } diff --git a/fastx_programmability/framework/src/natives/id.rs b/fastx_programmability/framework/src/natives/id.rs index d40478ed804cd..23211b47834d6 100644 --- a/fastx_programmability/framework/src/natives/id.rs +++ b/fastx_programmability/framework/src/natives/id.rs @@ -9,7 +9,7 @@ use move_vm_types::{ loaded_data::runtime_types::Type, natives::function::{native_gas, NativeResult}, pop_arg, - values::Value, + values::{StructRef, Value}, }; use smallvec::smallvec; use std::collections::VecDeque; @@ -34,3 +34,20 @@ pub fn bytes_to_address( Ok(NativeResult::ok(cost, smallvec![Value::address(addr)])) } + +pub fn get_id( + context: &mut NativeContext, + ty_args: Vec, + mut args: VecDeque, +) -> PartialVMResult { + debug_assert!(ty_args.len() == 1); + debug_assert!(args.len() == 1); + + let obj = pop_arg!(args, StructRef); + let id_field = obj.borrow_field(0)?; + + // TODO: what should the cost of this be? + let cost = native_gas(context.cost_table(), NativeCostIndex::SIGNER_BORROW, 0); + + Ok(NativeResult::ok(cost, smallvec![id_field])) +} diff --git a/fastx_programmability/framework/src/natives/mod.rs b/fastx_programmability/framework/src/natives/mod.rs index cf4a0b5ab2d16..f02eddb548ed4 100644 --- a/fastx_programmability/framework/src/natives/mod.rs +++ b/fastx_programmability/framework/src/natives/mod.rs @@ -16,6 +16,7 @@ pub fn all_natives( const FASTX_NATIVES: &[(&str, &str, NativeFunction)] = &[ ("Event", "emit", event::emit), ("ID", "bytes_to_address", id::bytes_to_address), + ("ID", "get_id", id::get_id), ("Transfer", "transfer_internal", transfer::transfer_internal), ( "Transfer", diff --git a/fastx_programmability/framework/tests/IDTests.move b/fastx_programmability/framework/tests/IDTests.move new file mode 100644 index 0000000000000..b013fe0835f63 --- /dev/null +++ b/fastx_programmability/framework/tests/IDTests.move @@ -0,0 +1,21 @@ +#[test_only] +module FastX::IDTests { + use FastX::ID; + use FastX::TxContext; + + const ID_BYTES_MISMATCH: u64 = 0; + + struct Object has key, drop { + id: ID::ID, + } + + #[test] + fun test_get_id() { + let ctx = TxContext::dummy(); + let id = TxContext::new_id(&mut ctx); + let id_bytes = *ID::get_inner(&id); + let obj = Object { id }; + + assert!(ID::get_id_bytes(&obj) == &id_bytes, ID_BYTES_MISMATCH); + } +} \ No newline at end of file