//# publish module 0x1.Coin { struct Coin has store { value: u64 } public zero(): Self.Coin { label b0: return Coin { value: 0 }; } public value(c: &Self.Coin): u64 { label b0: return *&move(c).Coin::value; } public destroy_zero(c: Self.Coin) { label b0: Coin { } = move(c); _ = (); return; } } //# publish module 0x1.YYZ { struct YYZ { unused: bool } } //# publish module 0x1.M { import 0x1.Coin; import 0x1.signer; import 0x1.YYZ; struct Foo has store { x: T } struct CoinWrapper has key { f: Self.Foo> } struct InnerWrapper has key { f: Self.Foo} struct Inner has store { b: vector } public coin_wrapper(account: &signer, c: Coin.Coin) { let foo: Self.Foo>; let coin_wrapper: Self.CoinWrapper; label b0: foo = Foo> {x: move(c)}; coin_wrapper = CoinWrapper {f: move(foo)}; move_to(move(account), move(coin_wrapper)); return; } public inner_wrapper(account: &signer, b: vector) { let foo: Self.Foo; let inner_wrapper: Self.InnerWrapper; let inner: Self.Inner; label b0: inner = Inner { b: move(b) }; foo = Foo {x: move(inner)}; inner_wrapper = InnerWrapper {f: move(foo)}; move_to(move(account), move(inner_wrapper)); return; } public get_coin_value(account: &signer): u64 acquires CoinWrapper { let sender: address; let coin_wrapper_ref: &Self.CoinWrapper; let foo_ref: &Self.Foo>; let coin_ref: &Coin.Coin; label b0: sender = signer.address_of(copy(account)); coin_wrapper_ref = borrow_global(move(sender)); foo_ref = &move(coin_wrapper_ref).CoinWrapper::f; coin_ref = &move(foo_ref).Foo>::x; return Coin.value(move(coin_ref)); } public get_inner(account: &signer): vector acquires InnerWrapper { let sender: address; let inner_wrapper_ref: &Self.InnerWrapper; let foo_ref: &Self.Foo; let inner_ref: &Self.Inner; label b0: sender = signer.address_of(copy(account)); inner_wrapper_ref = borrow_global(move(sender)); foo_ref = &move(inner_wrapper_ref).InnerWrapper::f; inner_ref = &move(foo_ref).Foo::x; return *(&move(inner_ref).Inner::b); } public destroy(account: &signer): Coin.Coin acquires CoinWrapper { let sender: address; let coin_wrapper: Self.CoinWrapper; let f: Self.Foo>; let x: Coin.Coin; label b0: sender = signer.address_of(copy(account)); coin_wrapper = move_from(move(sender)); CoinWrapper {f} = move(coin_wrapper); Foo> {x} = move(f); return move(x); } } //# run --signers 0x1 import 0x1.M; import 0x1.YYZ; import 0x1.Coin; main(account: signer) { let coin: Coin.Coin; let byte: vector; label b0: byte = h"bac1ac"; coin = Coin.zero(); M.coin_wrapper(&account, move(coin)); M.inner_wrapper(&account, move(byte)); return; } //# run --signers 0x1 import 0x1.M; import 0x1.YYZ; import 0x1.Coin; main(account: signer) { let coin: Coin.Coin; let byte: vector; label b0: byte = h"bac1ac"; assert(M.get_coin_value(&account) == 0, 4); assert(M.get_inner(&account) == move(byte), 4); return; } //# run --signers 0x1 import 0x1.M; import 0x1.YYZ; import 0x1.Coin; main(account: signer) { let coin: Coin.Coin; label b0: coin = M.destroy(&account); Coin.destroy_zero(move(coin)); return; }