A complete blockchain implementation featuring: - synord: Full node with GHOSTDAG consensus - explorer-web: Modern React blockchain explorer with 3D DAG visualization - CLI wallet and tools - Smart contract SDK and example contracts (DEX, NFT, token) - WASM crypto library for browser/mobile
130 lines
3.7 KiB
Markdown
130 lines
3.7 KiB
Markdown
# 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/)
|