Smart contracts in Motoko
Motoko is a programming language developed specifically for ICP smart contracts. It is an actor-based language that is tightly integrated with the Internet Computer's platform features, such as canister lifecycle management, orthogonal persistence, and inter-canister messaging.
Motoko uses the actor model, meaning each canister runs independently with its own memory and message queue and uses garbage collection for automatic memory management. With Motoko's orthogonal persistence, your canister's data can be kept across application upgrades.
For building Bitcoin DeFi apps on the Internet Computer, Motoko is the most ICP-native language choice available:
- Purpose-built for ICP: Unlike general-purpose languages, Motoko was designed from the ground up with ICP in mind.
- Easy to learn: With syntax similar to JavaScript and TypeScript, it's approachable for web developers.
- Built-in features: Supports ICP-specific concepts like stable variables, cycles, and inter-canister calls out of the box.
- Strong typing: Offers static type checking and pattern matching for safe, predictable code.
Compiling Motoko to Wasm
Motoko compiles to WebAssembly (Wasm), the bytecode format used to run ICP smart contracts. The Motoko compiler (moc
) turns your .mo
files into Wasm binaries, which can then be deployed directly to the network using tools like dfx
.
Enhanced orthogonal persistence
One of Motoko's standout features is enhanced orthogonal persistence. This means that state is preserved automatically across canister upgrades, and you can manage transient and stable memory explicitly and declaratively. This significantly reduces the complexity of maintaining stateful smart contracts over time.
Using the Bitcoin API from Motoko
ICP supports direct integration with the Bitcoin network, and the Motoko provides methods to interact with the Bitcoin API, allowing ICP smart contracts to:
- Generate Bitcoin addresses (ECDSA or Schnorr)
- Read UTXOs and balances
- Construct and sign Bitcoin transactions
- Submit transactions to the Bitcoin mainnet, testnet, or regtest
For example, you can use Motoko to generate a BTC address like this:
/// Returns the P2PKH address of this canister at a specific derivation path.
public func get_p2pkh_address() : async BitcoinAddress {
await P2pkh.get_address(ecdsa_canister_actor, NETWORK, KEY_NAME, p2pkhDerivationPath());
};