# Synor Contract Template

A starter template for building smart contracts on the Synor blockchain.

## Quick Start

1. **Copy this template**:
   ```bash
   cp -r contracts/template contracts/my-contract
   ```

2. **Update Cargo.toml**:
   - Change `name = "synor-template"` to your contract name
   - Update description and authors

3. **Modify src/lib.rs**:
   - Update storage key prefixes (replace `template:` with your contract name)
   - Add your methods and logic
   - Define your events

4. **Build**:
   ```bash
   rustup target add wasm32-unknown-unknown  # First time only
   cargo build --manifest-path contracts/my-contract/Cargo.toml \
       --target wasm32-unknown-unknown --release
   ```

5. **Deploy**:
   ```bash
   synor contract deploy target/wasm32-unknown-unknown/release/my_contract.wasm
   ```

> **Important**: Contracts must be built with `--target wasm32-unknown-unknown`.
> Building on native targets (without this flag) will fail because contracts use
> `#![no_std]` with custom allocator/panic handlers provided only for WASM.

## Template Features

This template demonstrates common patterns:

### Storage Patterns
- Simple values (`storage::get`, `storage::set`)
- Maps with string keys (`storage::get_with_suffix`, `storage::set_with_suffix`)
- Custom struct storage (with `BorshSerialize`/`BorshDeserialize`)

### Authorization
- Owner-only functions using `require_auth!`
- Ownership transfer

### Events
- Custom event structs with `emit!`
- Built-in SDK events (`OwnershipTransferred`, etc.)

### Error Handling
- Input validation with `require!`
- Proper error types

## Contract Methods

| Method | Access | Description |
|--------|--------|-------------|
| `init(name)` | Once | Initialize the contract |
| `owner()` | Public | Get owner address |
| `get_name()` | Public | Get contract name |
| `set_name(name)` | Owner | Update contract name |
| `get_counter()` | Public | Get counter value |
| `increment(amount)` | Public | Increment counter |
| `get_value(key)` | Public | Get value from map |
| `set_value(key, value)` | Public | Set value in map |
| `transfer_ownership(new_owner)` | Owner | Transfer ownership |

## Project Structure

```
template/
├── Cargo.toml      # Package manifest
├── README.md       # This file
└── src/
    └── lib.rs      # Contract implementation
```

## Available SDK Features

### Macros
- `entry_point!(init_fn, call_fn)` - Define contract entry points
- `require!(condition, error)` - Assert with error
- `require_auth!(address)` - Assert caller matches address
- `emit!(event)` - Emit an event

### Functions
- `caller()` - Get the calling address
- `value()` - Get the sent value
- `timestamp()` - Get block timestamp
- `block_height()` - Get current block height

### Storage
- `storage::get<T>(key)` - Read a value
- `storage::set(key, value)` - Write a value
- `storage::get_with_suffix<T>(prefix, suffix)` - Read from map
- `storage::set_with_suffix(prefix, suffix, value)` - Write to map
- `storage::Map<K, V>` - Typed map helper

### Types
- `Address` - 34-byte address
- `Error` - Contract error types
- `Result<T>` - Result type alias

## Optimization Tips

1. **Keep contracts small**: Use `opt-level = "z"` in release profile
2. **Use `#![no_std]`**: Avoid standard library overhead
3. **Optimize with wasm-opt**:
   ```bash
   wasm-opt -Oz -o optimized.wasm contract.wasm
   ```
4. **Batch storage operations**: Minimize reads/writes
5. **Use fixed-size types**: Prefer `u64` over `usize`

## Testing

Currently, contracts are tested by:
1. Deploying to a local devnet
2. Using the synor CLI to interact
3. Verifying state changes

## Resources

- [Host Functions Reference](../HOST_FUNCTIONS.md)
- [Contract Examples](../) (token, nft, dex, staking)
- [Synor SDK Source](../../crates/synor-sdk/)
