//# publish module 0x1.M { import 0x1.signer; // Structures // // a generic struct struct Some has key { v: T } struct Value has store { val: u64 } struct Container has copy, drop, store { elem: T } // Functions // // return a `Container` public new_container(t: T): Self.Container { label b0: return Container{ elem: move(t) }; } // change the elem of a `Container` if T is copyable public change_container(c: &mut Self.Container, t: T) { label b0: *&mut move(c).Container::elem = move(t); return; } // destroy a `Container` and returns the `T` wrapped by it public destroy_container(c: Self.Container): T { let t: T; label b0: Container { elem: t } = move(c); return move(t); } // return a `Value` instance (a resource) public new_value(val: u64): Self.Value { label b0: return Value{ val: move(val) }; } // change the `val` in a `Value` instance public change_value(value: &mut Self.Value, val: u64) { label b0: *&mut move(value).Value::val = move(val); return; } // destroy `Value` and return the wrapped u64 public destroy_value(value: Self.Value): u64 { let v: u64; label b0: Value { val: v } = move(value); return move(v); } // publish a well known `Some` struct public publish_some_value(account: &signer) { let value: Self.Value; let some_of_value: Self.Some; label b0: value = Value { val: 100 }; some_of_value = Some{ v : move(value) }; move_to>(copy(account), move(some_of_value)); return; } // unpublish whatever was published in `publish_some_value()` public unpublish_some_value(account: &signer) acquires Some { let sender: address; let some_of_value: Self.Some; let value: Self.Value; let v: u64; label b0: sender = signer.address_of(move(account)); some_of_value = move_from>(move(sender)); Some { v: value } = move(some_of_value); Value { val: v } = move(value); assert(move(v) == 100, 100); return; } // publish a `Some` under sender account public publish_some(account: &signer, v: T) { let some_of_t: Self.Some; label b0: some_of_t = Some{ v: move(v) }; move_to>(move(account), move(some_of_t)); return; } // unpublish a `Some` under sender account public unpublish_some(account: &signer): T acquires Some { let sender: address; let some_of_t: Self.Some; let t: T; label b0: sender = signer.address_of(move(account)); some_of_t = move_from>(move(sender)); Some { v: t } = move(some_of_t); return move(t); } // whether an instance of Some exists under sender account public some_exists(account: &signer): bool { let sender: address; label b0: sender = signer.address_of(move(account)); return exists>(move(sender)); } // check a `Some` under sender account public check_some(account: &signer, val: T): T * bool acquires Some { let sender: address; let some: &Self.Some; let inner_ref: &T; let val_ref: &T; let equal: bool; label b0: sender = signer.address_of(move(account)); some = borrow_global>(move(sender)); inner_ref = &move(some).Some::v; val_ref = &val; equal = (move(inner_ref) == move(val_ref)); return move(val), move(equal); } // publish a `Some` under sender account public change_some(account: &signer, val: T) acquires Some { let sender: address; let some: &mut Self.Some; label b0: sender = signer.address_of(move(account)); some = borrow_global_mut>(move(sender)); *(&mut move(some).Some::v) = move(val); return; } } // // From here on there are a set of transactions over a set of published // resources Some. // It is best followed going line by line. They are effectively a single transaction // that publishes, uses and destroys resources but it's spread across multiple // transaction to test the MoveValue <-> byte[] conversions of the serializer // (effectively the publishing to store) // // // create, publish and exists //# run --args @0x1 import 0x1.M; main(account: signer) { label b0: assert(M.some_exists(&account) == false, 1010); assert(M.some_exists
(&account) == false, 1011); M.publish_some_value(&account); assert(M.some_exists(&account) == true, 1012); return; } //# run --args @0x1 import 0x1.M; main(account: signer) { label b0: assert(M.some_exists(&account) == true, 1020); assert(M.some_exists(&account) == false, 1021); M.publish_some(&account, 100); M.publish_some(&account, true); assert(M.some_exists(&account) == true, 1022); assert(M.some_exists(&account) == true, 1023); assert(M.some_exists
(&account) == false, 1024); return; } //# run --args @0x1 import 0x1.M; main(account: signer) { label b0: assert(M.some_exists(&account) == true, 1030); assert(M.some_exists(&account) == true, 1031); assert(M.some_exists
(&account) == false, 1032); assert(M.some_exists>(&account) == false, 1033); M.publish_some
(&account, 0x0); M.publish_some>( &account, M.new_container(7) ); assert(M.some_exists
(&account) == true, 1034); assert(M.some_exists>(&account) == true, 1035); assert(M.some_exists>(&account) == false, 1036); assert(M.some_exists(&account) == true, 1037); M.publish_some>( &account, M.new_container( M.new_value(5) ) ); return; } // // borrows and mutations //# run --args @0x1 import 0x1.M; main(account: signer) { let eq: bool; let val: M.Value; label b0: _, eq = M.check_some(&account, true); assert(move(eq), 2010); _, eq = M.check_some(&account, 100); assert(move(eq), 2011); _, eq = M.check_some
(&account, 0x0); assert(move(eq), 2012); _, eq = M.check_some>(&account, M.new_container(7)); assert(move(eq), 2013); _, eq = M.check_some>(&account, M.new_container(10)); assert(!move(eq), 2014); val = M.new_value(5); val, eq = M.check_some(&account, move(val)); assert(!move(eq), 2015); _ = M.destroy_value(move(val)); return; } //# run --args @0x1 import 0x1.M; main(account: signer) { let eq: bool; label b0: M.change_some(&account, false); M.change_some(&account, 1); M.change_some
(&account, 0x01); M.change_some>(&account, M.new_container(20)); _, eq = M.check_some>(&account, M.new_container(20)); assert(move(eq), 2020); _, eq = M.check_some
(&account, 0x1); assert(move(eq), 2021); return; } // // unpublish, destroy and exists //# run --args @0x1 import 0x1.M; main(account: signer) { label b0: M.unpublish_some_value(&account); assert(M.some_exists(&account) == false, 3010); assert(M.some_exists
(&account) == true, 3011); assert(M.some_exists>(&account) == true, 3012); assert(M.some_exists>(&account) == false, 3013); return; } //# run --args @0x1 import 0x1.M; main(account: signer) { label b0: assert(M.some_exists>(&account) == true, 3020); assert(M.some_exists(&account) == false, 3021); assert(M.some_exists
(&account) == true, 3022); assert(M.unpublish_some(&account) == 1, 3023); assert(!M.unpublish_some(&account), 3024); assert( M.destroy_container( M.unpublish_some>(&account) ) == 20, 3025 ); assert(M.unpublish_some
(&account) == 0x01, 3026); assert(M.some_exists(&account) == false, 3027); assert(M.some_exists
(&account) == false, 3028); assert(M.some_exists>(&account) == false, 3029); return; } //# run --args @0x1 import 0x1.M; main(account: signer) { label b0: assert( M.destroy_value( M.destroy_container( M.unpublish_some>(&account) ) ) == 5, 3030 ); assert(M.some_exists(&account) == false, 3031); assert(M.some_exists
(&account) == false, 3032); assert(M.some_exists(&account) == false, 3033); assert(M.some_exists>(&account) == false, 3034); assert(M.some_exists>(&account) == false, 3035); assert(M.some_exists(&account) == false, 3036); return; }