Release Notes: PEPERMANENT

Here’s the final piece:

The quality is lowered here since I converted SVG into GIF format
The quality is lowered here since I converted SVG into GIF format

Let’s talk about PEPERMANENT.

  • How to confirm the permanence of PEPERMANENT

  • Walkthrough on creating a fully on-chain NFT on Bitcoin

  • Final words

How to confirm the permanence of PEPERMANENT

1. Go to xchain explorer, and see the Issuances tab. Click View in the initial issuance transaction.

Click the first transaction (issuance). The other transactions are about locking and making sure the asset is displayed correctly in wallets
Click the first transaction (issuance). The other transactions are about locking and making sure the asset is displayed correctly in wallets

2. You can already see the data in the description here but the better method is copying the transaction hash into your clipboard and resolving the op_return data either manually or through an API. This is what we’ll do now: Copy the transaction hash.

The transaction hash where the data is added to the chain
The transaction hash where the data is added to the chain

3. Now you have three choices. Choose one of the instructions below to extract the image URI.

3.a) Go to bitst.art and scroll to the “description” field under events.

Pay attention to the part after "image"
Pay attention to the part after "image"

The image element starts with data:image/svg…. and ends with …/svg%3e.

You can just copy-paste everything within the “image” element to any browser and it’ll show you your on-chain Pepe.

3.b) Visit JP Janssen’s decoder referring to this transaction and scroll down to the “Description” field. You’ll see the full data there.

Pay attention to the part after "image"
Pay attention to the part after "image"

Unfortunately, the formatting may not work when you copy-paste, so just right-click the “inspect” element.

Right-click and select "Inspect"
Right-click and select "Inspect"

Under the console, you’ll find the entire image URI.

The console has the right formatting
The console has the right formatting

The image element starts with data:image/svg…. and ends with …/svg%3e.

You can just copy-paste everything within the “image” element to any browser and it’ll show you your on-chain Pepe.

3.c) You can also do it manually. Follow JP Janssen’s guide and use the transaction where the data is added on-chain. Here’s the blockstream link to the Bitcoin transaction.

Note: The entire URI is a JSON file; but what you’re interested in is the image, which is located inside the image element of the JSON. In either option above in Step 3, the image element starts with data:image/svg…. and ends with …/svg%3e.

If you copy this string into any browser’s URL section, it’ll display the artwork.

Just copy and press Enter
Just copy and press Enter

Here’s the full image URI string:

data:image/svg+xml;utf8,%3csvg width='480' height='672' viewBox='0 0 480 672' xmlns='http://www.w3.org/2000/svg'%3e%3cfilter id='a' filterUnits='userSpaceOnUse'%3e%3cfeGaussianBlur in='SourceGraphic' stdDeviation='5' result='v'/%3e%3cfeGaussianBlur in='SourceGraphic' stdDeviation='10' result='w'/%3e%3cfeGaussianBlur in='SourceGraphic' stdDeviation='15' result='x'/%3e%3cfeGaussianBlur in='SourceGraphic' stdDeviation='20' result='y'/%3e%3cfeMerge%3e%3cfeMergeNode in='v'/%3e%3cfeMergeNode in='w'/%3e%3cfeMergeNode in='x'/%3e%3cfeMergeNode in='y'/%3e%3c/feMerge%3e%3c/filter%3e%3cfilter id='b'%3e%3cfeTurbulence baseFrequency='0.1'/%3e%3cfeDisplacementMap in='SourceGraphic' scale='12'/%3e%3c/filter%3e%3cpath d='M0 0h480v672H0z'%3e%3canimate attributeName='fill' from='%23000' to='%23222' dur='0.1s' repeatCount='indefinite'/%3e%3c/path%3e%3cg fill='%231a44f1'%3e%3cpath d='M69 389c38 274-101 237 294 238-4-145-113-259-284-240 260 47 239 9 239 15-7 275 196 240-262 222 12 21 62-225 13-235z'/%3e%3cpath d='M153 421c-139-69 41 215 182 187-270 97-54-305-66-142-323 268-21 2-116-45Z'/%3e%3canimate attributeName='fill-opacity' from='0.8' to='0.2' dur='0.1s' repeatCount='indefinite'/%3e%3c/g%3e%3cg fill='%231a44f1'%3e%3cpath d='M212 417c-128 78-123 197 9 190-282 116 100-225 88-62-39 176-23-18-97-128Z'/%3e%3canimate attributeName='fill-opacity' from='0.2' to='0.8' dur='0.1s' repeatCount='indefinite'/%3e%3c/g%3e%3cg style='filter:url(%23a)'%3e%3cg fill='%23fff' id='c'%3e%3cpath d='M36 707c15-17 24-61 19-86-9 60-16 44-19 86zm147 9c31-37 42-66 37-92-9 60-34 49-37 92z'/%3e%3cpath d='M220 718c13-25 7-85 9-103-15-10-9 86-9 103zm136-88c-16 10-10 56-10 82 9-18 3-61 10-81zm42-509c4-65-99-69-121-33 87-44 93-29 121 33z'/%3e%3cg%3e%3canimateTransform attributeName='transform' type='translate' from='0 0' to='0 -20' dur='0.2s' repeatCount='indefinite'/%3e%3cpath d='M61 358C-77 674 71 623 88 676c-3 25 51-260-8-310 61 88-21 449-24 254-48 132-72-137 5-262Zm262 31c41 27 91 383 33 258-32 111-31-181-47-256 3 426 138 306 14-2zm115-247c-30-22-93-42-153-19 46-2 122-20 153 19z'/%3e%3cpath d='M304 140c-30-22-83-68-143-17 84-34 112-22 143 17z'/%3e%3c/g%3e%3cpath d='M99 191c4-126 135-196 187-74C273 11 68 59 99 191zm359-22c-72-52-179 17-136-11 46-34 141-13 136 11z'/%3e%3cpath d='M325 161c-68-47-193 34-150 6 71-51 156-30 150-6zm135 38c-49 42-62 55-136 31 37 0 109 24 136-31zm-132 13c-19 36-69 27-150 4 63 32 113 23 151-4zM86 380c-76-23-58-205 12-221-88 55-84 212-12 221z'/%3e%3cpath d='M195 405c70 22 318-38 215-161 130 308-609 57-215 161z'/%3e%3cg style='filter:url(%23b)'%3e%3cpath d='M315 199c-3-2 3-26 6-25-83-38-118-8-148 14 75 54 122 13 142 11z'/%3e%3cpath d='M317 198c-3-2 2-25 5-24 32-31 119-22 129 9-33 51-144 23-134 15z'/%3e%3cg fill='%230c0705'%3e%3ccircle cx='249' cy='186' r='28'/%3e%3ccircle cx='385' cy='184' r='27'/%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cuse href='%23c'/%3e%3cpath d='M336 320c104 24-93 0-154-22 42 47 208 82 154 22z' fill='%23e2145f'%3e%3canimate attributeName='fill-opacity' from='0' to='0.8' dur='0.2s' repeatCount='indefinite'/%3e%3c/path%3e%3cpath fill='%23af6648' stroke='%23af6648' stroke-width='2'%3e%3canimate attributeName='d' from='m 277,327 c -150,-19 -133,0 -118,5 155,36 317,23 260,1 -22,1 -95,9 -208,-12 -57,-9 -83,-29 11,-20 178,39 256,-16 206,18 0,0 -10,26 -151,9 z' to='m 279,314 c -148,-30 -147,-47 -87,23 70,67 318,36 193,-30 39,29 -25,82 -171,20 -8,-3 -115,-81 10,-46 122,52 258,-41 185,19 0,0 -97,20 -130,13 z' dur='0.2s' repeatCount='indefinite'/%3e%3c/path%3e%3cg fill='%2367974c'%3e%3cg%3e%3canimate attributeName='fill-opacity' from='0.8' to='0.2' dur='0.1s' repeatCount='indefinite'/%3e%3cpath d='M184 253c-257 59-36 64-71 123 118-49-101-132 37-179-207 17 94 108 34 56zm-75-62c28-60 89-171 149-99 44 13-162-65-149 99zm216-45c65-15 42-40 96-5-51-12-144-33-96 5z'/%3e%3cpath d='M398 261c-33 23-230 42-192-6 121 91 40 7 192 6zM36 592c117-39-43-25 25-138-54 35-41 119-25 158zm325-70c-61 227 26 25-37-109 0 162 64 334 37 109zM200 654c-27-41-119 50-102-22 40 26 56 56 102 22Z'/%3e%3c/g%3e%3cg%3e%3canimate attributeName='fill-opacity' from='0.2' to='0.8' dur='0.2s' repeatCount='indefinite'/%3e%3cpath d='M117 216c-160 74 36 159 202 165-255 40-206-134-156-152 54 67-160 125-45-13zm170-113c43-39 42 0 84 5-11-63-34-2-84-5zm-157 86c63-54 18-81 130-70-54 35-140-17-130 70z'/%3e%3cpath d='M185 278c45-58 361 27 109 14 281-92-163 5-109-14zM72 581c17-118-56-57 1-145-78 46 59-194 9 145zm253 72c-27-41-86 57-69-15 40 26 56 50 69 15z'/%3e%3c/g%3e%3c/g%3e%3cuse href='%23e' x='136'/%3e%3cpath fill='none' stroke='%23fff' id='e'%3e%3canimate attributeName='d' from='m243 198c41-37 4-6 5 6 38-34 4-10 10 4 2-30-9-11-7-25-4 2-12 15-8 15z' to='m 237,183 c -9,24 44,-4 36,18 -6,17 -29,-1 -12,-1 20,0 -9,-65 -10,-3 -1,30 -7,-33 -13,-14 z' dur='0.2s' repeatCount='indefinite'/%3e%3c/path%3e%3cuse href='%23e' x='136'/%3e%3c/svg%3e

Bitcoin On-Chain NFT Creation Walkthrough

First a little bit of history: The first 100% on-chain ownable artwork on Bitcoin was created by JP Janssen. His work, OLGA, to this day remains one of the most significant relics in the entire NFT space regardless of the chain.

Mr. Janssen encoded OLGA (which is a JPG file) in Bitcoin transactions. He chose to store in a transaction that isn’t linked to the OLGA token itself (the method resembles how CryptoPunks stored its images on-chain on a separate contract).

I use SVG file type in my art, because SVG is vector graphics. Since it’s based on a mathematical framework, it takes significantly less space than raster graphic files. SVG can also scale infinitely and has no frame loss in its animations (technically infinite frame per second). These advantages make SVG one of the best file types for the metaverse, especially an on-chain one.

While creating the artwork, I do a lot of optimizations. Already while drawing on inkscape, I minimize the number of nodes on each pathway without losing the aesthetic feel. Then I edit the drawing directly in code; removing decimals, grouping similar property assets, adding animations, effects, etc. This stage is usually 80% of the work - making sure I create an aesthetically pleasing artwork while minimizing its cost storage.

A single arm's node optimization takes 1+ hour
A single arm's node optimization takes 1+ hour

Up until this point, we haven’t uploaded anything on-chain. In Ethereum, this is pretty easy - you just update the tokenURI and all marketplaces & wallets will be able to read the on-chain data and display the artwork. Unfortunately, this isn’t common practice in Bitcoin. So I had to get creative a bit.

I noticed that description fields in Counterparty wallets were being stored within Bitcoin transactions (as part of op_return). This is usually a link to a JSON file, stored on a centralized server or Arweave. But what if I stored my JSON file which included my SVG file directly in it?

Make no mistake, once you add a weird JSON to your description, nothing will be visible on any Counterparty wallets, or Counterparty explorers. These fields are not designed for this purpose.

That wasn't the design for the description field
That wasn't the design for the description field

But artists use mediums outside their original purpose all the time.

So that’s exactly what I did.

I wanted to make sure that the file gets stored on-chain “at issuance” (not added later). So I minted PEPERMANENT directly with the long JSON file including the SVG artwork, which cost me ~$200 to store on-chain. Then I ran another transaction to add an Arweave link so that wallets and explorers could recognize the artwork.

Actions taken to store it on-chain and displaying on wallets/explorers
Actions taken to store it on-chain and displaying on wallets/explorers

Final Words

Storing the most iconic web3 character on Bitcoin itself is a very interesting idea to me. I also wanted it to look aesthetically pleasing, which I hope I managed. This of course required a lot of optimization because storing stuff on Bitcoin is expensive AF. Beyond that, I had a lot of fun creating the artwork. There is some reference to my earlier pieces in PEPERMANENT. I’d love it if people could find that reference.

I deployed PEPERMANENT on 2022-11-23, but I had to wait for Fake Rares to approve me and add the card to the directory before I announced it, which is why the hype started only recently.

I hope everyone enjoys PEPERMANENT as much as I did.

Update: PEPERMANENT is now fully sold and can only be bought on the secondary market. As of this writing, there are no dispensers available on Counterparty. The only available assets seem to be on Emblem Vault on Ethereum. The current floor price is 0.69E.

Feels immutable man.

Subscribe to Chainleft
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.