Your First Smart Contract
Welcome! NEAR accounts can store small apps known as smart contracts. In this quick tutorial, we will guide you in creating your first contract on the NEAR testnet!
Join us in creating a friendly auction contract, which allows users to place bids, track the highest bidder and claim tokens at the end of the auction.
Want to jump right into the code without setting up a local dev environment?
Checkout NEAR Playground for an easy-to-use online IDE w/ pre-configured templates.

Prerequisites
Before starting, make sure to set up your development environment.
Working on Windows?
See our blog post getting started on NEAR using Windows for a step-by-step guide on how to set up WSL and your environment
- 🌐 JavaScript
- 🦀 Rust
- 🐍 Python
# Install Node.js using nvm (more options in: https://nodejs.org/en/download)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
nvm install latest
# ⚠️ For Mac Silicon users only, Rosetta is needed to compile contracts
# /usr/sbin/softwareupdate --install-rosetta --agree-to-license
# Install NEAR CLI to deploy and interact with the contract
npm install -g near-cli-rs@latest
# Install Rust: https://www.rust-lang.org/tools/install
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Contracts will be compiled to wasm, so we need to add the wasm target
rustup target add wasm32-unknown-unknown
# Install NEAR CLI-RS to deploy and interact with the contract
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/near-cli-rs/releases/latest/download/near-cli-rs-installer.sh | sh
# Install cargo near to help building the contract
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/latest/download/cargo-near-installer.sh | sh
Python quickstart tutorial is coming soon!
In the meantime, please check out the hello-near example.
Some near-cli commands have two versions - a full one and a short one. If you want to explore all options provided by near-cli use the interactive mode.
There is no need to have a testnet account to follow this tutorial.
However, if you want to create one, you can do so through a wallet, and use it from the near-cli by invoking near login.
Need some testnet tokens? Use the faucet to top-up your account.
Creating the Contract
Create a smart contract by using one of the scaffolding tools and following their instructions:
- 🌐 JavaScript
- 🦀 Rust
- 🐍 Python
npx create-near-app@latest
Creating a project using create-near-app
This will generate a project with the following structure:
hello-near
├── sandbox-test # sandbox testing
│ └── main.ava.js
├── src # contract's code
│ └── contract.ts
├── README.md
├── package.json # package manager
└── tsconfig.json
We recommend you to name your project hello-near for this tutorial, but feel free to use any name you prefer
cargo near
Creating a project using cargo near new
This will generate a project with the following structure:
hello-near
├── src # contract's code
│ └── lib.rs
├── tests # sandbox testing
│ └── test_basics.rs
├── Cargo.toml # package manager
├── Cargo.lock # package lock file
├── README.md
└── rust-toolchain.toml
You can skip the interactive menu and create a new project with specific name running the following command:
cargo near new hello-near
hello-near is the name we chose for this project so the tutorial is simpler to follow, but for future projects feel free to use any name you prefer
Python quickstart tutorial is coming soon!
In the meantime, please check out the hello-near example.
The Contract
The auction smart contract allows users to place bids, track the highest bidder and claim tokens at the end of the auction. Therefore it exposes following methods to interact with it:
init: to initialize the contract with auction parametersbid: to place a bid in the auctionclaim: to claim tokens after the auction endsget_highest_bid: to fetch the highest bid and bidder informationget_auction_end_time: to retrieve the auction end timeget_auctioneer: to get the auctioneer's account IDget_claimed: to check if a bidder has claimed their tokens
- 🌐 JavaScript
- 🦀 Rust
- 🐍 Python
Loading...
Loading...
Python quickstart tutorial is coming soon!
In the meantime, please check out the hello-near example.
After finishing this tutorial, check our contract's anatomy page to learn more about the contract's structure
Test the Contract
Building and testing the contract is as simple as running the test command. The contract will be compiled and the tests will be executed.
- 🌐 JavaScript
- 🦀 Rust
- 🐍 Python
npm run test
Failing tests?
Make sure that you are using node v18, v20 or v22 - you can manage multiple versions using nvm - and that you have Rosetta installed on MacOS if you have an Apple Silicon processor.
cargo test
Python quickstart tutorial is coming soon!
In the meantime, please check out the hello-near example.
In the background, these commands are calling the build tools for each language and using a Sandbox to test the contract.
Testing the contracts within a Sandbox allows you to understand how the contract will behave once deployed to the network while having total control over the testing environment.
Create a Testnet Account
Now that you know the contract is passing the tests, let's create a testnet account in which to deploy the contract. near-cli supports two versions of some commands - full and short one. It's up to you which format you prefer, but full version provides more features.
- Short
- Full
# Replace <your-account-id.testnet> with a custom name
near create-account <your-account-id.testnet> --useFaucet
Example Result
$> near create-account lovely-event.testnet --useFaucet
# New account "lovely-event.testnet" created successfully
# Replace <your-account-id.testnet> with a custom name
near account create-account sponsor-by-faucet-service <your-account-id.testnet> autogenerate-new-keypair save-to-keychain network-config testnet create
Example Result
$> near account create-account sponsor-by-faucet-service lovely-event.testnet autogenerate-new-keypair save-to-keychain network-config testnet create
# New account "lovely-event.testnet" created successfully
Remember that you can create a named account through any wallet (i.e. MyNearWallet) and then use it from the near-cli by invoking near login.
When running the near account create-account command in a headless Linux environment (e.g., WSL), the save-to-keychain option may fail due to platform limitations. Use save-to-legacy-keychain instead of save-to-keychain to ensure compatibility.
Build the Contract
When you are ready to create a build of the contract run a one-line command depending on your environment.
- 🌐 JavaScript
- 🦀 Rust
- 🐍 Python
npm run build
cargo near build
For this tutorial we will use the non-reproducible-wasm option when building the contract, but please know that you can create a reproducible build if you have Docker installed
Python quickstart tutorial is coming soon!
In the meantime, please check out the hello-near example.
Deploy the Contract
Having our account created, we can now deploy the contract:
- 🌐 JavaScript
- 🦀 Rust
- 🐍 Python
- Short
- Full
near deploy <created-account> ./build/hello_near.wasm
near contract deploy <created-account> use-file ./build/hello_near.wasm without-init-call network-config testnet sign-with-keychain send
- Short
- Full
near deploy <created-account> ./target/near/hello_near.wasm
near contract deploy <created-account> use-file ./target/near/hello_near.wasm without-init-call network-config testnet sign-with-keychain send
Python quickstart tutorial is coming soon!
In the meantime, please check out the hello-near example.
Congrats! Your contract now lives in the NEAR testnet network.
Interacting with the Contract
To interact with your deployed smart contract, you can call its functions through the command line.
Initialize the Contract
Let's start by initializing the contract with the auction parameters. The init method sets up the auction with an end time and the auctioneer's account ID. It can be called only by contract's account itself.
- Short
- Full
> near call <created-account> init '{"end_time": "<time-in-nanoseconds>", "auctioneer": "<created-account>"}' --accountId <created-account>
> near contract call-function as-transaction <created-account> init json-args '{"end_time": "<time-in-nanoseconds>", "auctioneer": "<auctioneer-account>"}' prepaid-gas '30.0 Tgas' attached-deposit '0 NEAR' sign-as <created-account> network-config testnet sign-with-keychain send
<auctioneer-account> should be replaced with the account ID of the auctioneer, which can be the same as <created-account> or a different account.
Place a Bid
We can now place a bid in the auction using the bid method. This method allows users to place their bids by attaching a deposit. The highest bid and bidder information will be updated accordingly and will be stored on the contract's storage, and thus requires a user to sign a transaction in order to be executed (as well as attaching a deposit).
- Short
- Full
> near call <created-account> bid '{}' --deposit 0.01 --accountId <created-account>
> near contract call-function as-transaction <created-account> bid json-args {} prepaid-gas '30.0 Tgas' attached-deposit '0.01 NEAR' sign-as <created-account> network-config testnet sign-with-keychain send
Notice that we are signing the transaction using <created-account>, so in this case, we are asking the contract's account to call its own function
Claim
After the auction ends, the highest bidder can claim their tokens using the claim method. Actually, anyone can call this method on behalf of the highest bidder to transfer the tokens to them. This method requires a signed transaction but does not require any deposit.
- Short
- Full
> near call <created-account> claim '{}' --accountId <created-account>
> near contract call-function as-transaction <created-account> claim json-args {} prepaid-gas '30.0 Tgas' attached-deposit '0 NEAR' sign-as <created-account> network-config testnet sign-with-keychain send
Get Highest Bid
The get_highest_bid function only reads from the contract's state, and can thus be called for free.
- Short
- Full
> near view <created-account> get_highest_bid '{}'
> near contract call-function as-read-only <created-account> get_highest_bid json-args {} network-config testnet now
Get Auction End Time
Same as get_highest_bid, the get_auction_end_time function only reads from the contract's state, and can thus be called for free.
- Short
- Full
> near view <created-account> get_auction_end_time '{}'
> near contract call-function as-read-only <created-account> get_auction_end_time json-args {} network-config testnet now
Get Auctioneer
Same as get_highest_bid, the get_auctioneer function only reads from the contract's state, and can thus be called for free.
- Short
- Full
> near view <created-account> get_auctioneer '{}'
> near contract call-function as-read-only <created-account> get_auctioneer json-args {} network-config testnet now
Get Claimed
Same as get_highest_bid, the get_claimed function only reads from the contract's state, and can thus be called for free.
- Short
- Full
> near view <created-account> get_claimed '{}'
> near contract call-function as-read-only <created-account> get_claimed json-args {} network-config testnet now
Moving Forward
That's it for the quickstart tutorial. You have now seen a fully functional contract with a minimal user interface and testing.
To better understand the contract's structure, check our contract's anatomy page.
If you prefer to see more examples, check our examples page.
At the time of this writing, this example works with the following versions:
- node:
22.18.0 - rustc:
1.86.0 - near-cli-rs:
0.22.0 - cargo-near:
0.16.1 - Python:
3.13 - near-sdk-py:
0.7.3 - uvx nearc:
0.9.2 - emscripten:
4.0.9(required for Python contracts)