Lets put SVGs on chain and save over 60% in gas fees

cSVG is a dictionary compression/decompression library to put SVG data on the ETH blockchain for way less gas.

Lets take a look at the following SVG:

csvg before
As written, this SVG is 848 bytes. If we remove all of the decimals and extra spaces and pack this in as small as the possible, we can get the size down to ~475 bytes. This is pretty good, but we can do better.

cSVG takes this a few steps further and stores properties and tags as indexes and uses fixed point floats stored in two bytes for decimal numbers and colors stores as 3 bytes to minimize on-chain storage. By using the cSVG library, this SVG is compressed into a much smaller array of bytes

csvg after
The total size of this cSVG is 175 bytes. This results in more than 60% savings in gas to put this SVG on chain!

When it is time to render the image, calling the render function of the cSVG smart contract decompresses the cSVG into an actual SVG and returns it as a string. Below is the result
< xmlns="http://www.w3.org/2000/svg"width="320.0" height="320.0" >
If you store your SVGs in the cSVG smart contract, then you can also make use of the composability functionality, allowing you to stack many SVGs on to of eachother. The tag id 0xFF lets the decompressor know that you want to inject another partial SVG into your SVG.

If the image above was stored on chain as svgId #1 and a red opaque circle was stored as #2, you can easily stack those images on top of eachother. The cSVG would be:

csvg stacked
And the resulting image would be:

< xmlns="http://www.w3.org/2000/svg"width="320.0" height="320.0" >
Please connect your wallet
Please connect your wallet

How to

Take an SVGs and paste it into the upload form a few lines at a time. Use the Check SVG button and inspect the code of the SVG presented to you to ensure it is encoding properly.

Let me know if you have any issues

cSVG saves a lot of space on-chain by compressing data. These savings come with some trade off's
  • Nesting too deeply or having extremely complex paths will throw an error
  • All numbers must be less than 1023 and more than -1024
  • Decimals have a granularity of 0.03 (if you specify 1.04 it will automatically round to 1.03)
  • All stroke and fill properties must be defined with a color code (#ff0000 etc)
  • To make a stroke or fill transparent, set fill-opacity or stroke-opacity to 0