About: An IoT and blockChain developer;
interested in Cloud Computing;
love coding...
Location:
Saskatoon, Saskatchewan
Joined:
Oct 9, 2021
Tutorial - play with an auction demo based on ERC721
Publish Date: Jun 6 '22
8 0
This tutorial is meant for those with a basic knowledge of Ethereum and smart contracts, who have some knowledge of Solidity.
The purpose of building this blog is to write down the detailed operation history and my memo for learning the dApps and solidity programming.
If you are also interested and want to get hands dirty, just follow these steps below and have fun!~
This contract is for selling NFT. The general idea is that users (accounts) can send their bids to the contract for winning the NFT during a bidding period. The initial ownership for this NFT is the contract owner account[0] / address(0)(assume that we deploy the contract using account[0]). The highest bidder will win the ownership of the NFT. Participants can withdraw their bids when the selling ends.
Remark: This is test version not for production use.
Overview of the contract code (EnglishAuction.sol):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;
interface IERC721 {
function transferFrom (
address from,
address to,
uint nftId
) external;
}
contract EnglishAuction {
event Start();
event Bid(address indexed sender, uint amount);
event Withdraw(address indexed bidder, uint amount);
event End(address highestBidder, uint amount);
IERC721 public immutable nft;
uint public immutable nftId;
address payable public immutable seller;
uint32 public endAt;
bool public started;
bool public ended;
address public highestBidder;
uint public highestBid;
mapping(address => uint) public bids;
constructor(address _nft, uint _nftId, uint _startingBid) {
nft = IERC721(_nft);
nftId = _nftId;
seller = payable(msg.sender);
highestBid = _startingBid;
}
function start() external {
require(msg.sender == seller, "not seller");
require(!started, "started");
started = true;
endAt = uint32(block.timestamp + 60); // 60 seconds should be long enough for the Demo and test.
nft.transferFrom(seller, address(this), nftId);
emit Start();
}
function bid() external payable {
require(started, "not started");
require(block.timestamp < endAt, "ended");
require(msg.value > highestBid, " value < highest bid");
if (highestBidder != address(0)) {
bids[highestBidder] += highestBid;
}
highestBid = msg.value;
highestBidder = msg.sender;
emit Bid(msg.sender, msg.value);
}
function withdraw() external {
uint bal = bids[msg.sender];
bids[msg.sender] = 0;
payable(msg.sender).transfer(bal);
emit Withdraw(msg.sender, bal);
}
function end() external {
require(started, "not started");
require(!ended, "ended!");
require(block.timestamp >= endAt, "not ended");
ended = true;
if (highestBidder != address(0)) {
nft.transferFrom(address(this), highestBidder, nftId);
seller.transfer(highestBid);
} else {
nft.transferFrom(address(this), seller, nftId);
}
emit End(highestBidder, highestBid);
}
}
License identifier and compiler version are defined at first. Interfaces are identified using the “interface” keyword. It contains function signatures without the function definition implementation. It can be used in a contract to call functions in another contract. Event can be emitted in a specific function and the log can be seen in decoded output of each function call. State variables are those whose values are permanently stored in a contract storage. Immutable state variables cannot be modified after the contract has been constructed.
A constructor is executed upon contract creation, and where we initialize the newly created NFT address, NFT ID, seller (that is contract owner account[0]) and the initial bid.
NFT ownership will be transferred from the contract owner to this contract when seller clicking "start" to execute start() function. 60 seconds is specified as the bidding period. You can always modify it as a longer time. When the bidding process started, users can send their bids with specific value by executing bid().
Function end() is used to terminate the bidding process and withdraw is to withdraw bids from this contract.
Mint the NFT ownership to account[0] by pasting the address(0), and specifying the nftId as your lucky number:
2 - Deploy the EnglishAuction.sol contract
ERC721 contract address, nftId and starting bids are needed:
3 - Approval for NFT ownership transmission
Contract ERC721 needs account[0] to approve that the contract EnglishAuction will be able to transfer the NFT ownership from the seller to the contract itself. contract address of EnglishAuction and nftId are needed:
4 - Start the bidding process
The seller can start the process by clicking start; other accounts can send bids with a specified amount of ETH:
5 - Check the Bidder information and ownership
Git repository
Welcome to visit the Git repo for source code, and feel free to reach me by leaving a message below or via email found in my profile.