Documentation
Learn about the Python subset supported by Tsukumogami, safety guarantees, and how to write transpilable contracts.
Overview
Tsukumogami transpiles a carefully constrained subset of Python into production-ready smart contracts. The subset is designed to ensure:
- Determinism — Same input always produces same output
- Auditability — Generated code is readable and reviewable
- Gas Predictability — Bounded execution costs
- Safety — Compile-time guarantees prevent common vulnerabilities
Python Subset
Supported Features
Not Supported
Decorators
@contract— Marks a class as a smart contract@contract
class MyContract:
...@entry— Transaction entry point (state-mutating)@entry
def transfer(self, to: Address, amount: Uint256) -> bool:
...@view— Read-only function (no state changes)@view
def get_balance(self, account: Address) -> Uint256:
return self.balances[account]@event— Defines an emittable event@event
class Transfer:
sender: Address
recipient: Address
amount: Uint256@storage— Marks persistent storage@storage
class State:
owner: Address
total: Uint256Type Mappings
| Python | Solidity | Rust | Move |
|---|---|---|---|
| int | int256 | i64 | u64 |
| bool | bool | bool | bool |
| str | string | String | String |
| Uint256 | uint256 | u128 | u256 |
| Address | address | Pubkey | address |
| Bytes32 | bytes32 | [u8; 32] | vector<u8> |
| Mapping[K, V] | mapping(K => V) | HashMap<K, V> | Table<K, V> |
| Array[T] | T[] | Vec<T> | vector<T> |
Safety Rules
Mandatory Type Annotations
All function parameters, return types, and storage variables must have explicit type annotations. This enables static analysis and deterministic code generation.
No Recursion
Direct or indirect recursion is not allowed. All iterative patterns must use explicit loops with bounded iterations.
No Floating Point
Floating-point numbers are not supported due to non-deterministic behavior across platforms. Use integer arithmetic or fixed-point representations.
Bounded Loops
All loops must have a clear upper bound that can be determined at compile time. This ensures predictable gas costs and prevents infinite loops.
Examples
Simple Counter
Basic state management with increment/decrement
class="syntax-decorator">@contractclass Counter: count: Uint256 class="syntax-decorator">@entry def increment(self) -> None: self.count += 1 class="syntax-decorator">@view def get(self) -> Uint256: return self.countcontract Counter { uint256 public count; function increment() external { count += 1; } function get() external view returns (uint256) { return count; }}Access Control
Owner-restricted operations
class="syntax-decorator">@contractclass Ownable: owner: Address def __init__(self) -> None: self.owner = msg.sender class="syntax-decorator">@entry def restricted_action(self) -> None: assert msg.sender == self.owner class=class="syntax-string">"syntax-comment"># ... actioncontract Ownable { address public owner; constructor() { owner = msg.sender; } function restrictedAction() external { require(msg.sender == owner); class=class="syntax-string">"syntax-comment">// ... action }}Token Balance
Mapping-based balance tracking
class="syntax-decorator">@contractclass Token: balances: Mapping[Address, Uint256] class="syntax-decorator">@entry def transfer(self, to: Address, amount: Uint256) -> bool: assert self.balances[msg.sender] >= amount self.balances[msg.sender] -= amount self.balances[to] += amount return Truecontract Token { mapping(address => uint256) public balances; function transfer(address to, uint256 amount) external returns (bool) { require(balances[msg.sender] >= amount); balances[msg.sender] -= amount; balances[to] += amount; return true; }}