Anyone can use this iNFT pattern as a way to securely host websites by publishing them as NFTs.
These iNFT websites can be their own browser experience, in addition to (along with all other standard NFTs) being automatically included in public NFT marketplaces such as OpenSea, within a wallet such as Rainbow or shown on a DAO dashboard such as KALI.
Though the IPFS hosted HTML in this “proto iNFT” proof-of-concept is opinionated for a “legal seals” application, the iNFT’s pattern generally and especially up to that point is unopinionated.
Here is the “proto iNFT” as rendered by Mirror.xyz (the metadata’s “image” value isn’t intended to be the iNFT’s background, despite being shown as such in the Mirror.xyz ‘s rendering at time of publication):
Please visit the “interface tokens” article for context:
Here’s what an iNFT looks like in OpenSea (sans scrollbar sizing mistake):
Clicking on the parent flip
button (lower flip
button) cycles through the NFT’s 3 sides:
OpenSea’s iframes are sandbox iframes that don’t allow-same-origin
, so the “proto iNFT” ’s PDF side can’t be displayed on OpenSea. Instead, the iNFT offers the base64 workaround described in the “proto iNFT side-2” image shown above.
Using the iNFT’s parent smart contract as a self-referencing oracle that side-3 relies on for trustless-stateful reporting is described in the “interface tokens” article shared above.
The “proto iNFT” ’s side-1 plays with nesting 2-sides within it. Clicking on the child flip
button (upper flip
button) shown in the “proto iNFT side-1” image above offers a backside form that modifies the front-side via the reprint
button:
Though this result is opinionated for “legal seals” and other experiments, the general concepts include:
sides, and nested sides, for a physical token inspired ‘tiled’ interface
a side can be static, and potentially entirely onchain, e.g. a base64 PDF side
a side modifies a different side, e.g. a backside modifies a front-side
outsides sources, including the NFT’s own smart contract, can modify a side
The “proto iNFT” ’s smart contract is at:
It uses a Wrappr contract but minted through PolygonScan rather than Wrappr’s UI found here:
If a unique 0x address mints with the Wrappr’s UI, or through PolygonScan, that 0x address will be automatically added to the “proto iNFT” ‘s side-3 0x addresses listed below the ‘signer under seal’ title.
This is a screenshot of the “proto iNFT” ’s minting transaction:
The “proto iNFT” ’s minting transaction is here:
The uri uses the base64 pattern described in the “interface tokens” article shared above:
Plugging the base64 into a browser renders the “proto iNFT” ’s onchain JSON metadata:
This is the animation_uri
HTML within the JSON’s base64 rendered as text:
<!DOCTYPE html>
<html>
<head>
<title>proto iNFT</title>
<script src="https://cdn.jsdelivr.net/npm/web3@1.2.9/dist/web3.min.js"></script>
</head>
<body>
<iframe id="$0" width="100%" height="500" style="display: block"></iframe>
<script id="app">
( function app() {
async function request() {
_0.response = await fetch( _0.ipfs )
; _0.string.parent += await _0
.response.text()
; _0.base64 = _0.string.parent
.replace( _0.prefix, '' )
; _0.string.child = atob(
_0.base64
)
; _0.json = JSON.parse(
_0.string.child
)
; _0.iframe.src = _0.json
.animation_url
;
}
function loop( $0 ) {
_0.contract.methods.KeyIndex( $0 )
.call().then( $1 => {
_0.version[
$1.key
] = $1.version
;
if ( $0 < _0.count ) {
_0.loop( $0 +1 )
; return
;
}
_0.next()
;
} )
.catch( $0 => {
console.error( $0 )
;
} )
;
}
function next() {
_0.contract.methods.KeyValue(
'proto iNFT'
, _0.version[ 'proto iNFT' ]
).call().then( $0 => {
_0.ipfs += $0
; _0.request()
;
} ).catch( $0 => {
console.error( $0 )
;
} )
;
}
const _0 = new App
; _0.contract = new _0.web3.eth
.Contract( _0.abi, _0.address )
; _0.contract.methods.KeyCount().call()
.then( $0 => {
_0.count = $0
; _0.loop( 0 )
;
} )
.catch( $0 => {
console.error( $0 )
;
} )
;
function App() {
this.abi = [... redacted]
; this.address = '0x02ef4cd76c44b781'
+ '302dd34142051704a94aabec'
; this.base64 = null
; this.contract = null
; this.count = null
; this.iframe = document
.getElementById( '$0' )
; this.ipfs = ''
; this.json = null
; this.loop = loop
; this.next = next
; this.prefix = 'data:application/js'
+ 'on;base64,'
; this.response = null
; this.request = request
; this.string = {}
; this.string.parent = ''
; this.string.child = ''
; this.version = {}
; this.web3 = new Web3(
new Web3.providers.HttpProvider(
redacted
)
)
;
}
} )( this )
</script>
</body>
</html>
This animation_uri
HTML is as-small-a-footprint-as-possible wrapper, for:
minimum onchain storage, given how expensive onchain data costs
doesn’t include any upgradable aspects of the “proto iNFT,” since it’s not upgradable
One of the ways the animation_uri
HTML keeps its footprint down is by using as-small-a-footprint-as-possible upgradable onchain smart contract oracle, found here:
The smart contact is a simple key-value pair object, that also has LIFO versioning for the value.
In the iNFT use case, by changing the proto iNFT key-value’s value to a different DNS hosted HTML file, the “proto iNFT” is updated to the new link. For best practice as of now, the value should be an IPFS hosted HTML file.
This IPFS hosted HTML file can be large. The IPFS hosted HTML for this current “proto iNFT” version is ~4000 lines long.
NFTs, “iNFTs,” as the way to distribute website client-side files:
publishes to as many places at once as possible
versioning is well-managed and transparent
marketplaces and other last-mile distributors manage HTTPS certificates
trustless, censor-resistant and commodified website-objects
token ID (smart-contract array “port”) #0 could be the UI used to mint the token, helping protect against malicious minting dapps
Here’s the “proto iNFT” as a website hosted by OpenSea:
Since this version of the “proto iNFT” isn’t a sandbox iframe, but rather the top-level DOM, it can display the parent side-2 PDF as intended:
iNFTs have a very interesting client-server-blockchain 3-sided dynamic to explore.
However, the chance to have a client-blockchain 2-sided dynamic is arguably far more important for progressive decentralization.
“proto iNFT” relies on an Alchemy blockchain server, as well as JavaScript library CDN servers. It’s a thin, but nevertheless server-dependent, client-server-blockchain 3-sided dynamic.
A client-blockchain 2-sided dynamic is not yet possible when using onchain oracles, unfortunately.