https://ergoauctions.org now supports audio NFTs - check it out here!
You can issue your audio NFT using https://ergoutils.org.
https://ergoauctions.org now supports audio NFTs - check it out here!
You can issue your audio NFT using https://ergoutils.org.
Please note that the link to audio has to be direct!
When you paste the link in the field in ergoutils, you should be able to listen to the audio in the player that shows up, otherwise, your link is not direct.
The auction house now supports artist page. Anyone can click on the artist address to see all his works.
Artists can share their page (all their artworks) on their socials. Example: Ergo Auction House
In general, if you for example have 3 addresses address1, address2, and address3 then your page will be: /#/auction/active?type=picture&artist=address1,address2,address3 - you can share your page to both present all your artworks and show authenticity of NFTs.
The artist of an artwork is determined by who has sent the necessary funds to issue the artwork. So I suggest to use a Yoroi wallet and use just a few addresses in that wallet for your artworks to be presentable easily,
This is honestly amazing, thank you so much!
In this thread, I am going to discuss a solution for having NFT Royalty functionality on Ergo.
Our goal is to pay the artist each time his artwork is auctioned and sold with some percentage of the amount.
To achieve that, we can enforce the box with the same ID as the NFT to be provided to the auction contract. Then the contract can make sure that some percentage of the auction amount goes to the contract that is (was) protecting that box - that contract is the artist’s address or a proxy contract which is also spendable by the artist.
The following is the new auction contract that supports custom tokens (e.g., SigUSD), royalties, and timestamp as auction duration:
{
val seller = SELF.R4[Coll[Byte]].get
val endTime = SELF.R5[Long].get
val minBidDelta = SELF.R6[Long].get
val currBidder = SELF.R8[Coll[Byte]].get
// auction currency can be any token like SigUSD
val isCurrencyERG = SELF.tokens.size == 1
val getAuctionCurrency = {(b: Box) => {
if (isCurrencyERG) Coll[Byte]()
else SELF.tokens(0)._1
}}
val getAuctionBid = {(b: Box) => {
if (isCurrencyERG) b.value
else SELF.tokens(0)._2
}}
val currBid = getAuctionBid(SELF)
val extendThreshold = 30 * 60 * 1000L // 30 mins
val extendNum = 40 * 60 * 1000L // 40 mins
// this is a bid
val auctionLogic = if (CONTEXT.preHeader.timestamp < endTime) {
val newSelf = OUTPUTS(0) // new auction box
val oldBidRefundBox = OUTPUTS(1) // refund box
// we extend the auction end time if the bid is placed near the very end
val newEndTime = if (endTime - HEIGHT <= extendThreshold) endTime + extendNum
else endTime
// preserve auctioned tokens
newSelf.tokens(0) == SELF.tokens(0) &&
// correct value and contract for the new box
getAuctionBid(newSelf) >= getAuctionBid(SELF) + minBidDelta &&
newSelf.propositionBytes == SELF.propositionBytes &&
// shouldn't be able to add tokens - will change the currency from ERG to a worthless token
SELF.tokens.size == newSelf.tokens.size &&
// currency must be the same
getAuctionCurrency(SELF) == getAuctionCurrency(newSelf) &&
// refund the previous bidder
oldBidRefundBox.propositionBytes == currBidder &&
getAuctionBid(oldBidRefundBox) >= currBid &&
// preserve the auction config
newSelf.R4[Coll[Byte]].get == seller &&
newSelf.R5[Long].get == newEndTime &&
newSelf.R6[Long].get == minBidDelta &&
newSelf.R9[Coll[Byte]] == SELF.R9[Coll[Byte]] &&
newSelf.R7[Coll[Byte]] == SELF.R7[Coll[Byte]]
// auction has ended
} else {
val winnerBox = OUTPUTS(0)
val sellerBox = OUTPUTS(1)
val feeBox = OUTPUTS(2)
val artistRoyalty = OUTPUTS(3)
val originalIssuanceBox = artistRoyalty.R4[Box].get
val dataInput = CONTEXT.dataInputs(0)
val auctionFee = currBid / dataInput.R4[Int].get
val feeTo = dataInput.R5[Coll[Byte]].get
val artistShare = currBid / dataInput.R6[Int].get
val artistGetsHisShare = {
originalIssuanceBox.id == blake2b256(originalIssuanceBox.bytes) && // the box has integrity
originalIssuanceBox.id == SELF.tokens(0)._1 && // the same ID as the NFT
getAuctionBid(artistRoyalty) >= artistShare && // gets at least the percentage defined in the auction config box
artistRoyalty.propositionBytes == originalIssuanceBox.propositionBytes // goes to the artist
}
dataInput.tokens(0)._1 == auctionTwinToken &&
feeBox.value >= auctionFee &&
feeBox.propositionBytes == feeTo &&
winnerBox.tokens(0) == SELF.tokens(0) &&
winnerBox.propositionBytes == currBidder &&
sellerBox.value >= currBid - auctionFee - maxFee * 2 &&
sellerBox.propositionBytes == seller &&
artistGetsHisShare
}
sigmaProp(auctionLogic)
}
@kushti @scalahub and others, please audit when you find the time - at least the changed/added parts.
Even royalties!! That is a godsend, thank you so much!
A brief guide on how royalties will work would be greatly appreciated
A predefined percentage of every auction will go to the original artist. The percentage is a global config and can be modified.
This is really great! I’m sure it will boost adoption of ergo NFTs .
Maybe it is worth to make an EIP out of it ?
very good upgrade for artists
As @kushti said, will be good to have an EIP for this. Few details to be clarified:
tokens(1)
in non-Erg auctions? I am assuming tokens(0)
is the NFT/tokens being auctioned and tokens(1)
is the auction currency in non-Erg auctionsCan you add comments at the beginning of the code to explain? (example below)
// R4 The seller's sigmaProp
// R5 The end time in millis
// R6 min bid delta
// R7 ...
// R8 Current bidder's sitmaProp
// R9 ...
// tokens(0) the tokens being auctions (if I understood correctly)
// tokens(1) the auction currency for non-erg auctions, otherwise empty
// dataInput(0) ...
This seems incorrect:
// preserve auctioned tokens
newSelf.tokens(0) == SELF.tokens(0) && // tokens(0) preserved
// correct value and contract for the new box
getAuctionBid(newSelf) >= getAuctionBid(SELF) + minBidDelta &&
// tokens(0) not preserved above
because getAuctionBid
operates on tokens(0)
and so the tokens are preserved in one and not in the other line. This is related to next comment.
Also, the following seems incorrect:
val getAuctionCurrency = {(b: Box) => {
if (isCurrencyERG) Coll[Byte]()
else SELF.tokens(0)._1
}}
val getAuctionBid = {(b: Box) => {
if (isCurrencyERG) b.value
else SELF.tokens(0)._2
}}
do you mean following?
val getAuctionCurrency = {(b: Box) => {
if (isCurrencyERG) Coll[Byte]()
else b.tokens(1)._1 // should be b instead of SELF, and tokens(1)
}}
val getAuctionBid = {(b: Box) => {
if (isCurrencyERG) b.value
else b.tokens(1)._2 // should be b instead of SELF, and tokens(1)
}}
In preserving the auction config for a bid case, we also need to ensure that R8 is a Coll[Byte]
, otherwise someone may set it to another type and make the box unspendable.
I’ll add more comments if any after the above is clarified
Sure, will do that with addressing comments also.
Trying to list an NFT using Yoroi wallet is there any instructions thanks. NFT is an image
Thanks, I’ll check out the video here is an example of my NFT. I am also going to work with an artist to bring a limited collection of NFT if I get success with my first ERGO collection I will create more. Is there any option to add an IPFS hash to the image within the auction for the winning bidder so that the higher-res images can be downloaded?
Here is an example of what I can up with this is AI art generated by a neural network.
I am still thinking up some ideas. Since ETH blockchain is pricey for NFT I am pointing my artist friends more towards ERGO.
Ergo Auction House and Ergo Utils now support IPFS.
Any artwork (picture, audio) issued from now on, will be upload to IPFS.
Stay tuned for more updates.
Another use-case for recently found property - using spent boxes as proof in ergo script:
An NFT collection is a category to which some NFTs belong. In the simplest case, an artist can have a “modern arts” collection and mint his modern arts in that collection. This way, an artist can have multiple collections to better present his artworks. This thread is a solution on how to handle collections in a decentralized way on Ergo.
Let’s consider each collection as an NFT on the blockchain with some properties like collection name, description, cover image, etc.
The artist can create a collection NFT and own it in his wallet. Once he wants to mint an artwork in that collection, he can simply mint the NFT by putting the box containing the collection NFT in the first input of his minting transaction. The artwork NFT ID will be equal to the box ID containing the collection NFT. This way, not only it is possible to verify that artwork belongs to a specific collection off-chain, but also it is possible to do so in ergo script. The way to do that is by simply providing the spent collection box to the contract, then the artwork NFT ID must be equal to the provided box’s ID and the provided box must include the collection NFT. It is obvious that no one but the artist can mint artwork in that collection!
Good idea, how we can calculate number of artwork tokens in a particular Collection ?
If you mean off-chain, some app that cares (e.g., auction house) will keep track of collections. Then when an artwork is issued it is obvious that it is in one of the collections that we are keeping track of because the NFT ID is among the collection IDs.