On OpenSea, most actions are off-chain, meaning they generate orders that are stored in the our system and can be fulfilled by a matching order from another user.
On Ethereum, whenever blockchain state is changed (e.g. when an asset moves from one account to another, or funds are traded between accounts), a transaction needs to occur. All transactions require Ether as payment, and in this form the payment is called gas. On many other marketplaces, users have to pay gas to list items for sale or to purchase them, but OpenSea is heavily optimized to prevent users from having to spend gas.
When a user lists an item for sale, they simply sign their intent to swap the item for payment. This intent is stored in the OpenSea system as a sell order, and does not create a transaction. When a buyer comes along and decides to accept the listing price, the buyer can sign a buy order as a counter-order to be matched with the sell order.
The buyer can pay the gas to create a transaction to match the two orders together, or the buyer can have OpenSea match it for them in the case of English Auctions. In that scenario, no user pays gas, and both orders are stored in the system. In all other scenarios, only the first order (the "maker" order) is stored.
All orders have a maker address field and taker address field. A maker is the first mover in a trade. Makers either declare intent to sell an item, or they declare intent to buy by bidding on one. A taker is the counterparty who responds to a maker's order by, respectively, either buying the item or accepting a bid on it.
Another way of putting this is that the maker is the user that is "creating liquidity," and the taker is the user that comes along and clears it away. On OpenSea, orders can be public, where the taker is the null address (
0x0000000000000000000000000000000000000000) and anyone can take the order, or private, where the taker is a specific user's account. Private orders can only be fulfilled by a specific account - no other account is allowed by the smart contract.
Bids and offers are both buy orders. You can differentiate between bids and offers by examining the
taker on the order object. Buy orders with the null address as their takers are offers. Buy orders with an address other than the null address as their takers are bids.
An offer is unsolicited. Any owner of an asset with an offer on it can accept the offer, even if the current owner was not the asset's owner at the time the offer was made.
A bid, in contrast, is made in response to the creation of an English auction. Bids are personal to the English auction's creator and are eligible to be automatically matched with the English auction's original sell order at the end of the English auction. The creator of an English auction may choose to accept a bid before the English auction ends. For more information on OpenSea's English auctions, see our article on the subject.
Orders have three time components on them:
created_date into a UTC timestamp called
createdTime, which is the number of seconds since the UNIX epoch (similar to
listing_time is the timestamp that the order will start to be fulfillable. For most orders this is right when they're made, but for English Auctions it's when the user wants the auction to end (this is added security to make sure it's not matchable until then).
expiration_time is the timestamp that the order will no longer be fulfillable ever. For most orders this is when the user wants them to expire, but for English Auctions it's set to a point later in the future, just so that OpenSea's servers have enough time to match them with the highest bid.