NFT Research - Creation and Distribution

Brass Tacks

We've come a long way! So far we've gone over several aspects of what an ideal NFT looks like based on Hive:

Now we're going to build our first NFT. This is a test/founders set and it'll live on DLUX.
DLUX "Hive aspect" Logo
This particular logo was made by turning our old logo by 90 degrees, When Hive got their logo we realized you could almost overlay the same H on ours when we did this. The file type here is "Scalable Vector Graphics" and if you're familiar with HTML the file would look very familiar to you.

Now our founders logo set will be from this, but each of the colors will be a psuedo-random color from the standard 16 color swatch. 000000, AA0000, 00AA00, AA5500, 0000AA, AA00AA, 00AAAA, AAAAAA, 555555, FF5555, 55FF55, FFFF55, 5555FF, FF55FF, 55FFFF, FFFFFF - Hex Colors Explained

To Accomplish this let's look at some of the actual code for the logo:

<defs>
 <style>.cls-1{fill:#393d49;}.cls-2{fill:#f0f;}.cls-3{fill:#005cff;}.cls-4{fill:#00ffc2;}</style>
</defs>

Vector graphics aren't pixel by pixel, they are like drawing a shape on Microsoft Paint then using the Fill tool to color your shape. All we have to do is change the the fill color to one of our 16 colors. cls-1 is the background color, so cls-2,3, and 4 will be our new unique colors.

To do this I wrote a script that can be executed in multiple contexts: Node.js, and three different ways in browser.

Let's examine this script:

<!DOCTYPE html>
//
function compile (message, display) {
const colors = ['#000000', '#AA0000', ...
const Base64 = { ...

First thing you'll notice is the commented out HTML, when run in eval or safe-eval these lines will be ignored.
the whole execution context is in the compile function.

        const flags = Base64.toFlags(message)
        var uColors = []
        var picker = 0
        for(var i = 0; i < 3; i++){
            for(var j = 0; j < 4; j++){
                if(flags[i*4 + j]){
                    picker += Math.pow(2,j+1)
                }
            }
            uColors.push(colors[picker])
            picker = 0
        }

        const SVG = '<svg ...  ... '

        if(display){
            document.getElementById('body').innerHTML = SVG
        } else {
            return SVG
        }
        
}
//

Here we can see the Unique Identifier getting turned into set of three colors, and our SVG getting modified with our colors.

When we run this code from a server it will look something like this:

fetch(`https://ipfs.io/ipfs/${set.script}`)
.then(r => {
    const code = `(//${r})(${UID})`
    SVG = safeEval(code)
})

The display flag won't be set and all this other code remains commented out, the function will just return the SVG, probably to be piped to the requester.

However, all of this can be run client side as well. Let's continue looking through our script.

/*
//
if (window.addEventListener) {
    window.addEventListener("message", onMessage, false);
    }
    else if (window.attachEvent) {
    window.attachEvent("onmessage", onMessage, false);
    }
    function onMessage(event) {
    var data = event.data;
    if (typeof(window[data.func]) == "function") {
    const got = window[data.func].call(null, data.message);
    window.parent.postMessage({
        'func': 'compiled',
        'message': got
        }, "*");
    }
    }
//
*/
//
//Append ?NFT_UID to the address bar to see that NFT. "...html?A6"const uid = location.href.split('?')[1]; if(uid)compile(uid, true)

With some more clever commenting this code meant for the browser will be ignored by the eval() function. With this window messaging code we can set this html file to run in an iFrame, which is exceptionally well sandboxed. Sending a window message with the UID payload will return the SVG via window messaging.

Of course you can run this in the browser via the eval function just like on Node.js.

Finally, You can open this script from any location, your computer, stored on a website, or directly from IPFS.
Then all you need to do is append ?UID to the url / location and the SVG will be appended to the body for you to see. Try it UID D8

  • 64 Possible Glyphs: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+=

UID 00

UID ==

UID A6

Are We There Yet?

“Dreams are what guide us, art is what defines us, math is what makes it all possible...”
― Mike Norton

Writing a script like this will be the hardest part of building an NFT set for our Layer 2s. We'll have some type definitions which will mostly be how to assemble UIDs on the Layer 2. The rest is submitting and paying fees to store, and then distributing the NFTs. Of course, pushing nearly everything to the client-side saves a whole lot of processing power and that's how we get to cut our fees closer to actual cost.

Let's go over setting up this set definition and getting our mint tokens.

For the time being this function will be restricted to test accounts, but hopefully after testing it will function the same way.

The JSON payload:

{
"name":"dlux",
"type": 1,
"script": "QmPsxgySUZibuojuUWCMQJpT2uZhijY4Cf7tuJKR8gpZqq",
"permlink": "disregardfiat/nft-announcement",
"start": "00",
"end": "==",
"royalty": 100,
"max_fee": 4000000
}

Type 0 is the no set IPFS... we won't be testing that yet. Type 1 is to use all UIDs in a Base64 Range: 00 -> == is 4096 individual NFTs. The script is the piece we already placed in IPFS to assemble our NFT in 4 ways. The permlink is the Hive announcement post, which should include a full copy of your IPFS script in the case that it isn't saved on IPFS, it will always be available on Hive and can be re-uploaded which should result in the same locator/hash. The royalty is how much of sale and transfer prices go back to the creators account, in units of 0.01%. So 100 is 1%.

Max Fee is how much you think setting this NFT up will cost based on the fees kept in the current layer 2 statistics. For example: This type 1 NFT will take up some space. So ~12 bytes for the average user account, stored twice. 5 bytes for last modified, and 2 bytes for the UID, twice. Plus about 10 bytes for formatting. Which is 44 bytes per NFT on average. If the current cost of bytes is 0.02 DLUX the total will be 3604.48 DLUX, So putting 4000 DLUX in the max field will ensure you didn't make a miscalculation that would charge your account 400,000 DLUX and make you very sad. Maybe the cost updates up or down a little bit, you're still in the right ball park.

Speaking of fees, once an NFT is issued, half gets burned and half goes into the days miner pool.

Once the definition is accepted into the system, there is a very small window where it can be deleted or modified. If any of the Mint Tokens get redeemed, the definition is immutable.

Distribution

The outcome of defining the above NFT will be 4096 Mint Tokens being placed in your account. You can then transfer, list, or auction these tokens. For our founders set @markegiles and I will keep 1/4th of the tokens each. For testing we'll distribute a mint token to all accounts currently holding more than 100 DLUX. We'll list some, auction some... and after testing list and auction the rest.

When you redeem a mint token, a Virtual Op will be made for the following block that will use that blocks witness signature as a seed for generating an effectively random NFT from the range of UIDs. This will prevent a witness from only submitting a transaction to redeem their token when they could forsee the outcome.

What's Next

The next post you see from me will be that actual NFT announcement, . So if you don't have 100 DLUX yet, there is still time. Hint -> DLUX DEX
Thanks for following along on my NFT research journey and all the support I've received.

H2
H3
H4
3 columns
2 columns
1 column
24 Comments