Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

113 lines (96 sloc) 4.22 KB
module LibraCoin {
// A resource representing the Libra coin
resource T {
// The value of the coin. May be zero
value: u64,
}
// A resource that grants access to `LibraCoin.mint`. Only the Association account has one.
resource MintCapability {}
// Return a reference to the MintCapability published under the sender's account. Fails if the
// sender does not have a MintCapability.
// Since only the Association account has a mint capability, this will only succeed if it is
// invoked by a transaction sent by that account.
public borrow_sender_mint_capability(): &R#Self.MintCapability {
let sender: address;
let capability_ref: &mut R#Self.MintCapability;
let capability_immut_ref: &R#Self.MintCapability;
sender = get_txn_sender();
capability_ref = borrow_global<MintCapability>(move(sender));
capability_immut_ref = freeze(move(capability_ref));
return move(capability_immut_ref);
}
// Mint a new LibraCoin.T worth `value`. The caller must have a reference to a MintCapability.
// Only the Association account can acquire such a reference, and it can do so only via
// `borrow_sender_mint_capability`
public mint(value: u64, capability: &R#Self.MintCapability): R#Self.T {
release(move(capability));
return T{value: move(value)};
}
// This procedure is private and thus can only be called by the VM internally. It is used only
// during genesis writeset creation to give a single MintCapability to the Association account.
grant_mint_capability() {
move_to_sender<MintCapability>(MintCapability{});
return;
}
// Create a new LibraCoin.T with a value of 0
public zero(): R#Self.T {
return T{value: 0};
}
// Public accessor for the value of a coin
public value(coin_ref: &R#Self.T): u64 {
return *&move(coin_ref).value;
}
// Splits the given coin into two and returns them both
// It leverages `Self.withdraw` for any verifications of the values
public split(coin: R#Self.T, amount: u64): R#Self.T * R#Self.T {
let other: R#Self.T;
other = Self.withdraw(&mut coin, move(amount));
return move(coin), move(other);
}
// "Divides" the given coin into two, where original coin is modified in place
// The original coin will have value = original value - `amount`
// The new coin will have a value = `amount`
// Fails if the coins value is less than `amount`
public withdraw(coin_ref: &mut R#Self.T, amount: u64): R#Self.T {
let value: u64;
// Check that `amount` is less than the coin's value
value = *(&mut copy(coin_ref).value);
assert(copy(value) >= copy(amount), 10);
// Split the coin
*(&mut move(coin_ref).value) = move(value) - copy(amount);
return T{value: move(amount)};
}
// Merges two coins and returns a new coin whose value is equal to the sum of the two inputs
public join(coin1: R#Self.T, coin2: R#Self.T): R#Self.T {
Self.deposit(&mut coin1, move(coin2));
return move(coin1);
}
// "Merges" the two coins
// The coin passed in by reference will have a value equal to the sum of the two coins
// The `check` coin is consumed in the process
public deposit(coin_ref: &mut R#Self.T, check: R#Self.T) {
let value: u64;
let check_value: u64;
value = *(&mut copy(coin_ref).value);
T { value: check_value } = move(check);
*(&mut move(coin_ref).value)= move(value) + move(check_value);
return;
}
// Destroy a coin
// Fails if the value is non-zero
// The amount of LibraCoin.T in the system is a tightly controlled property,
// so you cannot "burn" any non-zero amount of LibraCoin.T
public destroy_zero(coin: R#Self.T) {
let value: u64;
T { value } = move(coin);
assert(move(value) == 0, 11);
return;
}
// Temporary procedure that is called to burn off the collected gas fee
// In the future this will be replaced by the actual mechanism for collecting gas
public TODO_REMOVE_burn_gas_fee(coin: R#Self.T) {
let value: u64;
T { value } = move(coin);
return;
}
}
You can’t perform that action at this time.