# Create Smart Contracts with Sui Move
## Move.toml File
1. [package]: Your package metadata, such as name and version.
* name: The name of your package. Created by Sui Move compiler.
* version: The current version of your package. The Sui Move compiler creates the first value.
* published-at: The published address of the package. The Sui Move compiler does not automatically create this entry.

The published-at specifies the address that the dependency is published at

2. [dependencies]: List of packages that your package depends on. Initially, the Sui Framework is the only dependency, but you add third-party dependencies to this section as needed.

3. [addresses]: A list of named addresses. You can use the names listed as convenient aliases for the given addresses in the source code.

## Move.lock File
According to the indication on [Move.lock File page](https://docs.sui.io/build/move/lock-file) the file is not for us to edit


## Write a Sui Move Package
#### Create a package
```
sui move new my_first_package
```

#### The original Move.toml

#### Defining the Package
```
touch my_first_package/sources/my_module.move
```
```
module my_first_package::my_module {
// Part 1: Imports
use sui::object::{Self, UID};
use sui::transfer;
use sui::tx_context::{Self, TxContext};
// Part 2: Struct definitions
struct Sword has key, store {
id: UID,
magic: u64,
strength: u64,
}
struct Forge has key, store {
id: UID,
swords_created: u64,
}
// Part 3: Module initializer to be executed when this module is published
fun init(ctx: &mut TxContext) {
let admin = Forge {
id: object::new(ctx),
swords_created: 0,
};
// Transfer the forge object to the module/package publisher
transfer::transfer(admin, tx_context::sender(ctx));
}
// Part 4: Accessors required to read the struct attributes
public fun magic(self: &Sword): u64 {
self.magic
}
public fun strength(self: &Sword): u64 {
self.strength
}
public fun swords_created(self: &Forge): u64 {
self.swords_created
}
// Part 5: Public/entry functions (introduced later in the tutorial)
// Part 6: Private functions (if any)
}
```
## Build and Test Move Packages
Sui move build command
```
sui move build
```
#### Check the package name and the name in move file if the error occured

#### Build success

#### Testing a package
Sui move test command
```
sui move test
```
##### Without test code snippet

##### Syntax error

##### First test code snippet
Paste the first test code snippet and run sui move test
```
#[test]
public fun test_sword_create() {
use sui::tx_context;
// Create a dummy TxContext for testing
let ctx = tx_context::dummy();
// Create a sword
let sword = Sword {
id: object::new(&mut ctx),
magic: 42,
strength: 7,
};
// Check if accessor functions return correct values
assert!(magic(&sword) == 42 && strength(&sword) == 7, 1);
}
```

##### Second test code snippet
Update my_module.move and paste the following code snippet in part 5
```
public entry fun sword_create(magic: u64, strength: u64, recipient: address, ctx: &mut TxContext) {
use sui::transfer;
// create a sword
let sword = Sword {
id: object::new(ctx),
magic: magic,
strength: strength,
};
// transfer the sword
transfer::transfer(sword, recipient);
}
public entry fun sword_transfer(sword: Sword, recipient: address, _ctx: &mut TxContext) {
use sui::transfer;
// transfer the sword
transfer::transfer(sword, recipient);
}
```
Paste the second test code snippet and run sui move test
```
#[test]
fun test_sword_transactions() {
use sui::test_scenario;
// create test addresses representing users
let admin = @0xBABE;
let initial_owner = @0xCAFE;
let final_owner = @0xFACE;
// first transaction to emulate module initialization
let scenario_val = test_scenario::begin(admin);
let scenario = &mut scenario_val;
{
init(test_scenario::ctx(scenario));
};
// second transaction executed by admin to create the sword
test_scenario::next_tx(scenario, admin);
{
// create the sword and transfer it to the initial owner
sword_create(42, 7, initial_owner, test_scenario::ctx(scenario));
};
// third transaction executed by the initial sword owner
test_scenario::next_tx(scenario, initial_owner);
{
// extract the sword owned by the initial owner
let sword = test_scenario::take_from_sender<Sword>(scenario);
// transfer the sword to the final owner
sword_transfer(sword, final_owner, test_scenario::ctx(scenario))
};
// fourth transaction executed by the final sword owner
test_scenario::next_tx(scenario, final_owner);
{
// extract the sword owned by the final owner
let sword = test_scenario::take_from_sender<Sword>(scenario);
// verify that the sword has expected properties
assert!(magic(&sword) == 42 && strength(&sword) == 7, 1);
// return the sword to the object pool (it cannot be simply "dropped")
test_scenario::return_to_sender(scenario, sword)
};
test_scenario::end(scenario_val);
}
```

## Debug and Publish Move Packages
##### Debugging a package
Debug code snippet
```
use std::debug;
debug::print(&v);
```

```
debug::print_stack_trace();
```

##### Publishing a package

The third test code snippet for testing the module initialization
```
#[test]
public fun test_module_init() {
use sui::test_scenario;
// Create test address representing game admin
let admin = @0xBABE;
// First transaction to emulate module initialization
let scenario_val = test_scenario::begin(admin);
let scenario = &mut scenario_val;
{
init(test_scenario::ctx(scenario));
};
// Second transaction to check if the forge has been created
// and has initial value of zero swords created
test_scenario::next_tx(scenario, admin);
{
// Extract the Forge object
let forge = test_scenario::take_from_sender<Forge>(scenario);
// Verify number of created swords
assert!(swords_created(&forge) == 0, 1);
// Return the Forge object to the object pool
test_scenario::return_to_sender(scenario, forge);
};
test_scenario::end(scenario_val);
}
```


The final fixed code
```
module my_first_package::my_module {
// Part 1: Imports
use sui::object::{Self, UID};
use sui::transfer;
use sui::tx_context::{Self, TxContext};
// Part 2: Struct definitions
struct Sword has key, store {
id: UID,
magic: u64,
strength: u64,
}
struct Forge has key, store {
id: UID,
swords_created: u64,
}
// Part 3: Module initializer to be executed when this module is published
fun init(ctx: &mut TxContext) {
let admin = Forge {
id: object::new(ctx),
swords_created: 0,
};
// Transfer the forge object to the module/package publisher
transfer::transfer(admin, tx_context::sender(ctx));
}
// Part 4: Accessors required to read the struct attributes
public fun magic(self: &Sword): u64 {
self.magic
}
public fun strength(self: &Sword): u64 {
self.strength
}
public fun swords_created(self: &Forge): u64 {
self.swords_created
}
// Part 5: Public/entry functions (introduced later in the tutorial)
public entry fun sword_create(forge: &mut Forge, magic: u64, strength: u64, recipient: address, ctx: &mut TxContext) {
use sui::transfer;
use std::debug;
let v = 2345678;
debug::print(&v);
debug::print_stack_trace();
// create a sword
let sword = Sword {
id: object::new(ctx),
magic: magic,
strength: strength,
};
// transfer the sword
transfer::transfer(sword, recipient);
forge.swords_created = forge.swords_created + 1;
}
public entry fun sword_transfer(sword: Sword, recipient: address, _ctx: &mut TxContext) {
use sui::transfer;
// transfer the sword
transfer::transfer(sword, recipient);
}
// Part 6: Private functions (if any)
// testing
#[test]
public fun test_sword_create() {
use sui::transfer;
use sui::tx_context;
// Create a dummy TxContext for testing
let ctx = tx_context::dummy();
// Create a sword
let sword = Sword {
id: object::new(&mut ctx),
magic: 42,
strength: 7,
};
// Check if accessor functions return correct values
assert!(magic(&sword) == 42 && strength(&sword) == 7, 1);
// Create a dummy address and transfer the sword
let dummy_address = @0xCAFE;
transfer::transfer(sword, dummy_address);
}
#[test]
fun test_sword_transactions() {
use sui::test_scenario;
// create test addresses representing users
let admin = @0xBABE;
let initial_owner = @0xCAFE;
let final_owner = @0xFACE;
// first transaction to emulate module initialization
let scenario_val = test_scenario::begin(admin);
let scenario = &mut scenario_val;
{
init(test_scenario::ctx(scenario));
};
// second transaction executed by admin to create the sword
test_scenario::next_tx(scenario, admin);
{
let forge = test_scenario::take_from_sender<Forge>(scenario);
// create the sword and transfer it to the initial owner
sword_create(&mut forge, 42, 7, initial_owner, test_scenario::ctx(scenario));
test_scenario::return_to_sender(scenario, forge);
};
// third transaction executed by the initial sword owner
test_scenario::next_tx(scenario, initial_owner);
{
// extract the sword owned by the initial owner
let sword = test_scenario::take_from_sender<Sword>(scenario);
// transfer the sword to the final owner
sword_transfer(sword, final_owner, test_scenario::ctx(scenario))
};
// fourth transaction executed by the final sword owner
test_scenario::next_tx(scenario, final_owner);
{
// extract the sword owned by the final owner
let sword = test_scenario::take_from_sender<Sword>(scenario);
// verify that the sword has expected properties
assert!(magic(&sword) == 42 && strength(&sword) == 7, 1);
// return the sword to the object pool (it cannot be simply "dropped")
test_scenario::return_to_sender(scenario, sword)
};
test_scenario::end(scenario_val);
}
#[test]
public fun test_module_init() {
use sui::test_scenario;
// Create test address representing game admin
let admin = @0xBABE;
// First transaction to emulate module initialization
let scenario_val = test_scenario::begin(admin);
let scenario = &mut scenario_val;
{
init(test_scenario::ctx(scenario));
};
// Second transaction to check if the forge has been created
// and has initial value of zero swords created
test_scenario::next_tx(scenario, admin);
{
// Extract the Forge object
let forge = test_scenario::take_from_sender<Forge>(scenario);
// Verify number of created swords
assert!(swords_created(&forge) == 0, 1);
// Return the Forge object to the object pool
test_scenario::return_to_sender(scenario, forge);
};
test_scenario::end(scenario_val);
}
}
```

Publishing
```
sui client publish /home/garrick/Development/VSCode/sui_project/my_first_package --gas 0xd80cc482701eff5e85174194c5eab4a528e95f3c98ac4b1a95f0b09b2ee6d9bf --gas-budget 1000000
```

```
sui client publish /home/garrick/Development/VSCode/sui_project/my_first_package --gas 0xd80cc482701eff5e85174194c5eab4a528e95f3c98ac4b1a95f0b09b2ee6d9bf --gas-budget 100000000 --skip-dependency-verification
```


