📜 [專欄新文章] Gas Efficient Card Drawing in Solidity
✍️ Ping Chen
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
Assign random numbers as the index of newly minted NFTs
Scenario
The fun of generative art NFT projects depends on randomness. The industry standard is “blind box”, where both the images’ serial number and the NFTs’ index are predetermined but will be shifted randomly when the selling period ends. (They call it “reveal”) This approach effectively solves the randomness issue. However, it also requires buyers to wait until the campaign terminates. What if buyers want to know the exact card right away? We’ll need a reliable onchain card drawing solution.
The creator of Astrogator🐊 isn’t a fan of blind boxes; instead, it thinks unpacking cards right after purchase is more interesting.
Spec
When initializing this NFT contract, the creator will determine the total supply of it. And there will be an iterable function that is randomly picking a number from the remaining pool. The number must be in range and must not collide with any existing ones.
Our top priority is accessibility/gas efficiency. Given that gas cost on Ethereum is damn high nowadays, we need an elegant algorithm to control gas expanse at an acceptable range.
Achieving robust randomness isn’t the primary goal here. We assume there’s no strong financial incentive to cheat, so the RNG isn’t specified. Implementers can bring their own source of randomness that they think is good enough.
Implementation
Overview
The implementation is pretty short and straightforward. Imagine there’s an array that contains all remaining(unsold) cards. When drawIndex() is called, it generates a (uniform) random seed to draw a card from the array, shortens the array, and returns the selected card.
Algorithm
Drawing X cards from a deck with the same X amount of cards is equal to shuffling the deck and dealing them sequentially. It’s not a surprise that our algorithm is similar to random shuffling, and the only difference is turning that classic algo into an interactive version.
A typical random shuffle looks like this: for an array with N elements, you randomly pick a number i in (0,N), swap array[0] and array[i], then choose another number i in (1,N), swap array[1] and array[i], and so on. Eventually, you’ll get a mathematically random array in O(N) time.
So, the concept of our random card dealing is the same. When a user mints a new card, the smart contract picks a number in the array as NFT index, then grabs a number from the tail to fill the vacancy, in order to keep the array continuous.
Tweak
Furthermore, as long as the space of the NFT index is known, we don’t need to declare/initialize an array(which is super gas-intensive). Instead, assume there’s such an array that the n-th element is n, we don’t actually initialize it (so it is an array only contains “0”) until the rule is broken.
For the convenience of explanation, let’s call that mapping cache. If cache[i] is empty, it should be interpreted as i instead of 0. On the other hand, when a number is chosen and used, we’ll need to fill it up with another unused number. An intuitive method is to pick a number from the end of the array, since the length of the array is going to decrease by 1.
By doing so, the gas cost in the worst-case scenario is bound to be constant.
Performance and limitation
Comparing with the normal ascending index NFT minting, our random NFT implementation requires two extra SSTORE and one extra SLOAD, which cost 12600 ~ 27600 (5000+20000+2600) excess gas per token minted.
Theoretically, any instantly generated onchain random number is vulnerable. We can restrict contract interaction to mitigate risk. The mitigation is far from perfect, but it is the tradeoff that we have to accept.
ping.eth
Gas Efficient Card Drawing in Solidity was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
同時也有10000部Youtube影片,追蹤數超過2,910的網紅コバにゃんチャンネル,也在其Youtube影片中提到,...
intuitive drawing 在 AppWorks Facebook 的最佳解答
【Lesson #2 - Don't fall in love with your product】
Anyone who’s read Eric Ries’ “The Lean Startup” (and even those that didn’t) is all too familiar with the concept of a minimum viable product (MVP)—except when they’re not. Oftentimes through a perfectionist attitude or perhaps inherent fear of failure, founders create products that are more viable than minimum. That was the experience for Kevin Wong, the Co-founder/CEO of Origami Labs (AW#15), when they were creating their first product, a smart ring called ORII. According to Kevin, it was because he had such an attachment to this vision in his head, and anything short of that vision just felt like a concession. He’s since learned to accept a more iterative approach to product development and applying that lesson to his current product OFLO which enables smartphone-level comms in an audio wearable designed specifically for frontline staff.
—-
After establishing Origami Labs in 2015, we spent several years in R&D to create our first product ORII, a voice assistant smart ring that uses bone conduction technology to allow users to check new messages on their phone, control music, and complete other everyday tasks by simply holding your finger to your ear. This simple, intuitive finger-to-ear motion was what we loved so much about the product and what made it so easy to catch on and talk about. Our kickstarter campaign blew way past the initial goal in a matter of weeks. We became the first HK startup to place in TechCrunch Battlefield’s top 5. Press coverage was coming at us left and right and orders were coming from over 50 different countries. A lot of that, however, turned out to be false momentum.
In retrospect, ORII probably should have never been able to sell as well as it did. A lot of founders through sheer passion, grit, and willpower alone can build up early traction without breaking a sweat. But can someone 2 to 3 degrees away from them sell their product? That’s where founders really get measured in success. At some point, the product should be able to stand on its own two feet and speak for itself.
ORII could not. That elegant finger-to-ear motion that we were so enamored with ultimately became its achilles heel. It turns out, in 95 percent of the scenarios, you wouldn’t want to lift your hand to your head, especially in this wireless/hands-free age. We effectively fell in love with our product and stopped really listening to our customers. We thought it was perfect and became blind to any signals that said otherwise. I still remember going to visit Eric Migicovsky, YC partner and founder of Pebble watch, at his house. I showed him some of our early prototypes and he basically said “that’s cool, but it won’t work,” drawing upon his own experiences with hardware. Sure enough, after the initial media frenzy died down, orders started to visibly slow down. The final nail in the coffin was when Amazon released the echo loop (smart ring tied to Alexa), which mimicked our product feature-for-feature but better in every way.
As a founder, what you want to build makes so much sense. You see it with so much clarity that it’s almost unfathomable why someone wouldn’t understand. But innovation has to be an iterative process, as the market can only accept so much change. You need to put out a product that’s in some way necessary for people today, that gets some people using it on a frequent basis, and only from there can you practically grow it into something that you envisioned.
Applications for AW#22 are now open to founders targeting SEA, AI/IoT, or Blockchain/Defi -> https://bit.ly/36v9k8D