Addresses & Access Control
When you develop smart contracts there could be situations when you want to develop a module containing functions only your account can call.
For example, in Solidity it's the Ownable Smart Contract that brings the modifier onlyOwner which denies everyone the ability to call specific functions and allows only the owner to call them.
Let's create a new module with the same logic. We will use the Signer module to extract the transaction's sender address and compare it with the defined module owner.
1
address {{sender}} {
2
module OnlyOwnerStore {
3
use 0x01::Signer;
4
5
// Just a simple number storage.
6
struct U64 has store, key {
7
val: u64
8
}
9
10
// Owner address.
11
const OWNER : address = @{{sender}};
12
13
public fun store_u64(account: &signer, val: u64) {
14
assert(Signer::address_of(account) == OWNER, 101); // Throw error if function called is not from owner.
15
let foo = U64 { val: val };
16
move_to<U64>(account, foo);
17
}
18
19
// The function returns the owner's address.
20
public fun owner() : address {
21
OWNER
22
}
23
}
24
}
Copied!
If you put the address inside a variable, or as a literal, you should use the @ prefix (like in our example).
Only the owner address can call the store_u64 methods of the module, otherwise it sends an error:
1
assert(Signer::address_of(account) == OWNER, 101); // Throw error if function called is not from owner.
Copied!
Deploy the module under your address and use the following script as an experiment:
1
script {
2
use {{sender}}::OnlyOwnerStore;
3
4
fun owner_store(account: signer, n: u64) {
5
OnlyOwnerStore::store_u64(&account, n); // Will throw error if the account doesn't match the owner.
6
}
7
}
Copied!
Try to execute the script from different accounts, and you will see that it will return an error if the transaction sender is not the owner.
Last modified 1mo ago
Copy link