Basic Auction
In this section, we will analyze a simple auction contract, which allows users to place bids, track the highest bidder and claim tokens at the end of the auction. After, we will cover how to test the contract, as well as how to deploy it on testnet
.
During this tutorial, we will be relying on the Smart Contract Documentation and its different sections
Make sure to read the Prerequisites section and install the necessary tools before starting this tutorial
Cloning the contract
To get started we'll clone the tutorial's repository from GitHub. The repository contains the same smart contracts written in JavaScript (./contract-ts
) and Rust (./contract-rs
).
Navigate to the folder of the language you prefer, and then to the 01-basic-auction
folder.
- 🌐 JavaScript
- 🦀 Rust
git clone git@github.com:near-examples/auctions-tutorial.git
cd contract-ts/01-basic-auction
git clone git@github.com:near-examples/auctions-tutorial.git
cd contract-rs/01-basic-auction
The repository also contains a frontend application that interacts with the contract. You can find it in the frontends
folder. We will cover the frontend in a future section
The Contract's State
The contract allows users to place bids using $NEAR tokens and keeps track of the highest bidder. Lets start by looking at how we define the contract's state, this is, the data that the contract will store.
- 🌐 JavaScript
- 🦀 Rust
Loading...
Decorator
The first thing to notice is that the main class of the contract is marked using the @NearBindgen
decorator, which allows also to further specify that the contract must be initialized before being used.
Storage (aka State)
Another important information revealed by the code is that a contract can store different types of data, in this case:
highest_bid
is an instance of aBid
which stores:bid
: aBigInt
representing an amount of $NEAR tokens inyoctonear
(1Ⓝ = 10^24 yⓃ
)bidder
: anAccountId
that represents which account placed the bid
auction_end_time
aBigInt
representing aunix timestamp
in nanosecondsauctioneer
anAccountId
that states who can withdraw the funds at the end of the auctionclaimed
aboolean
that tracks if the auctioneer has claimed the funds
Loading...
Macros
A first thing to notice is the use of the #[near(contract_state)]
macro to denote the main structure and derive the PanicOnDefault
to specify that the contract must be initialized before being used.
We also use the #[near(serializers = [json, borsh])]
macro to enable both borsh
and JSON
(de)serialization of the Bid
structure. As a rule of thumb: use the json
serializer for structs that will be used as input / output of functions, and borsh
for those that will be saved to state.
Storage (aka State)
Another important information revealed by the code is that the contract can store different types of data.
highest_bid
is an instance of aBid
which stores:bid
: aNearToken
which simplifies handling $NEAR token amountsbidder
: theAccountId
that placed the bid
auction_end_time
is aU64
representing aunix timestamp
in nanosecondsauctioneer
anAccountId
that states who can withdraw the funds at the end of the auctionclaimed
aboolean
that tracks if the auctioneer has claimed the funds
You can read more about the contract's structure and the type of data it can store in the following documentation pages:
Initialization Function
Lets now take a look at the initialization function, which we need to call to determine the time at which the auction will end.
- 🌐 JavaScript
- 🦀 Rust
Loading...
Decorator
We denote the initialization function using the @initialize({ privateFunction: true })
decorator. The privateFunction:true
denotes that the function can only be called by the account on which the contract is deployed.