module HelloBlockchain::message { use std::string; use std::error; use aptos_std::event; use std::signer; struct MessageHolder has key { message: string::String, message_change_events: event::EventHandle, } struct MessageChangeEvent has drop, store { from_message: string::String, to_message: string::String, } /// There is no message present const ENO_MESSAGE: u64 = 0; public fun get_message(addr: address): string::String acquires MessageHolder { assert!(exists(addr), error::not_found(ENO_MESSAGE)); *&borrow_global(addr).message } public entry fun set_message(account: signer, message_bytes: vector) acquires MessageHolder { let message = string::utf8(message_bytes); let account_addr = signer::address_of(&account); if (!exists(account_addr)) { move_to(&account, MessageHolder { message, message_change_events: event::new_event_handle(&account), }) } else { let old_message_holder = borrow_global_mut(account_addr); let from_message = *&old_message_holder.message; event::emit_event(&mut old_message_holder.message_change_events, MessageChangeEvent { from_message, to_message: copy message, }); old_message_holder.message = message; } } #[test(account = @0x1)] public entry fun sender_can_set_message(account: signer) acquires MessageHolder { let addr = signer::address_of(&account); set_message(account, b"Hello, Blockchain"); assert!( get_message(addr) == string::utf8(b"Hello, Blockchain"), ENO_MESSAGE ); } }