Marketplace contract
Simple marketplace contract in Archetype
This one will be created from scratch.
The contract shown here is very basic and not optimised. It will be left to the reader to extend its functionalities.
Create a new file ./contracts/market.arl
The first line is the name declaration:
Next, we'll re-define the FA2 transfer parameter types that the contract will need to use to send transfer calls to the FA2 contract. They are very specific to the FA2 spec.
The marketplace contract will accept sale orders from collectors. For simplicity, the contract will accept any order, without checking the ownership of the token. Transfers will be enforced during the purchase and will fail if the seller does not own the tokens. The user interface will need to filter out invalid sale orders.
Orders are identified by a unique order id.
Parameters include the FA2 contract address (making this marketplace token-agnostic), the seller address, the token id, how many tokens are for sale, the price for each token, and an expiry date.
We need to keep track of orders:
Let's now create an entrypoint to list a token item for sale. The only conditions are that the amount is non-zero and that the expiry date is in the future. These conditions will prevent some invalid sale orders to be published.
However, the marketplace contract will not validate the amount of tokens owned by the seller. This would require tracking balance updates and add too much complexity to the smart contract. Instead, the orders will be filtered by the client.
Note how we use a simple counter to track the order ids. This will help us to enumerate the orders from the client side. It means that the client will have to get all order history and filter out expired and filled ones. This may not be optimal.
A more robust solution would be to run an off-chain indexer (or integrate an existing one such as tzkt), that will keep track of all the created and expired orders.
The seller should be able to change their mind and cancel the order. Note how we check that only the seller can call this entrypoint.
Now, buyers will call another entrypoint, that will do the following:
Check that the bought amount is non-zero:
r_buy_amount
Check that the order exists and that there are still tokens remaining to be sold:
r_order
Check that the amount sent with the transaction matches the price:
r_value
Check that the order didn't expire:
r_expired
Prepare the records required to call the
%transfer
entrypoint on the contract of the listed tokenUpdate the orders big map with the new amount
Call the FA2 contract to transfer the token from the seller to the buyer
Transfer the tez coins from the buyer to the seller
Important: By default, only the token owner is allowed to transfer their tokens. In this case, the buyer instructs the marketplace to transfer someone else's token. To allow this behavior, the token owner must approve the marketplace contract to transfer their tokens. On Tezos, we call the marketplace an operator
.
Adding the marketplace as an operator will be done in the next section (calling update_operators_for_all
on the token contract).
And our marketplace contract is now ready đŽâđ¨
Last updated