The punks that survived the cryptopocalypse, now on-chain.
The contracts are live on Mainnet and can be played with on Etherscan.
You may use the Radioactive Punks Operating System Website to view any punk's image and attributes stored on-chain with our PUNK LOOKUP dApp.
Radioactive Punks can be bought on our site and on OpenSea etc.
# Install hardhat and dev dependencies
yarn
# Compile the contracts
yarn compile
# Run tests comparing metadata of every punk
yarn test
# Run tests and keep coverage tabs
yarn coverage
Check the package.json to see all available commands.
Every metadata JSON file's attributes are checked individually.
Every image was checked manually by eye. I will write an image checker eventually but I'd have to spin up Selenium to properly do that and I'm too lazy to do that right now.
This is not an ERC-721 token, it is a ITokenURISupplier
and therefore contains a tokenURI
method similar to an ERC-721. It returns the on-chain metadata and image renderer for a given Radioactive Punks Token ID. We use this on the original contract for its METADATA_PROVENANCE_HASH
.
Deployment is modular and split across five main components:
RadioactivePunksRenderer
: responsible producing an on-chain tokenURI
RadioactivePunksBytesHyperstructure
: the encoded trait data of every punk as bytes in groups of 15
RadioactivePunksSVGChunk1
: gzipped SVG layer data for all punks
RadioactivePunksSVGChunk2
: gzipped SVG layer data for all punks
DataCompiler
: helpful functions for concatenating data into valid Data URI formats
Why no use of "SSTORE2" you may ask? Well once you fill up the entire contract with bytes or string data there is no efficiency to be gained by using SSTORE2, it actually reuquires more overhead.
The JS inflates the SVG layers and then appends them into the DOM, hidden. The JS has the encoded punk data injected into it as a string. The JS then uses that encoded data to selectively unhide the correct layers to render that punk. You now have a responsive SVG representation of your punk.
If you'd like to download your punk, right clicking anywhere on the page will trigger a 4k PNG download. It converts the SVG into a 4K PNG without any loss in quality.
Approximately 0.44560054 Ether
for all contracts combined.
- 13 gwei
- 0.16157843 ETH
- https://etherscan.io/tx/0xea7806d3943a14c162dc35ad3c720574f3e937934721f096fa7b9f21c722e669
- 19.27 gwei
- 0.103113579422061603 ETH
- https://etherscan.io/tx/0x59b98eb7bdf3a834965e8680d082ed2be6f4b7fa567042aae59c8209dbdd00ee
- 19 gwei
- 0.042472866 ETH
- https://etherscan.io/tx/0xbfbab49e347f052ed4433f87cac17bf102006583a83c200a580e6c4af6a6158b
- 20 gwei
- 0.10353022 ETH
- https://etherscan.io/tx/0xa90ec73a34f0855aa986c0e18dd17b250fdd0f72eb8a2bd472aa002989074657
- 20 gwei
- 0.03490544 ETH
- https://etherscan.io/tx/0xcbb0d7f7f7647318435e6aa08912318804352da122300461ad6ff88dc3d6922c
FFLate Mainnet
0xa942F946A35545F50792DA1Ea1ADf0c3b619b921
0xF10EeDb5ACE715d78e0f89eCd1Dfc3E5874f6e3c
Goerli
0x86A477028841854D9d02a5BD4fd6936216510A0f
0xB948057bdd71835b19Ff90aEa03FAd3Ebb66E870
Here's an example of getting the data of Punk #0 from the Cloudflare Public Ethereum RPC:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"eth_call", "params":[{"to":"0x5694010444cC8fbbed96c23a65FbC3714F624A26", "data":"0xc87b56dd0000000000000000000000000000000000000000000000000000000000000000"},"latest"]}' https://cloudflare-eth.com/
Want to create an API that serves a chained punk or your own similar on chain ITokenURISupplier
contract? Deploy a TokenURI Proxy Server using a free Heroku node and Public RPC Node!
- Had I reordered the BytesHyperstructure to use the same indexing as the original NFT contract, I could've avoided the need for the entire
TOKEN_ID_TO_BYTES_LOOKUP
data structure, saving quite a lot of gas on deployment. - I probably could've used SSTORE2 for a few minor strings to save minor amounts of gas upon deployment of the
RadioactivePunksRenderer.sol
file. - Maybe use EIP-681 or EIP-4804 on the original NFT contract's
tokenURI
though the contract haphazardly appends.json
at the end of every returned URI so that may never be a feasible thing for us.
This would not have been possible if I was not standing upon the shoulders of these giants:
- CryptoadzChained by Wattysart
- Roses by Dom.eth
- Crypto Coaster by Xtremetom
- Forgotten Runes Wizard Cult On Chain Migration
- Chaos Roads by Chain Leftist
- JPEG On Chain Curation
- Why on chain? by 0xmons
Please support their projects, art, and personal social media accounts.