Eeethers

This post was published 2023/06/13 & last updated 2023/07/27

ethgalleryonchaintokens

eeethers.xyz was the first smart contract I wrote that got published off of a testnet. At the time, multiple iterations of this were littered across Rinkby and Ropsten. Ultimately, it went live on Optimism. Feel free to check out the contract on Etherscan.

It was a pretty simple concept. Take the wallet address of whoever was minting the token, and split the it into 6 character chunks so it could be used as a color hex code. Since an address is 42 characters long we can get 7 unique color codes — though you do need to replace the 0x with a proper value (I used ff).

string[7] memory colors = [
  string.concat('ff', utils.getSlice(3, 6, _a)),
  utils.getSlice(7, 12, _a),
  utils.getSlice(13, 18, _a),
  utils.getSlice(19, 24, _a),
  utils.getSlice(25, 30, _a),
  utils.getSlice(31, 36, _a),
  utils.getSlice(37, 42, _a)
];

The whole project was bootstrapped with hot-chain-svg while dramatically improved the experience of composing an SVG in Solidity.

This:

string.concat(
  '<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1000 1000" style="background: #F2F3F5;">',
  svg.el(
    "filter",
    string.concat(svg.prop("id", "filter")),
    string.concat(
      svg.el("feTurbulence", string.concat(svg.prop("type", "fractalNoise"), svg.prop("baseFrequency", "0.01"), svg.prop("numOctaves", "3"), svg.prop("seed", utils.uint2str(_tokenId)))),
      svg.el("feDisplacementMap", string.concat(svg.prop("in", "SourceGraphic"), svg.prop("yChannelSelector", "R"), svg.prop("scale", "99")))
    )
  ),
  svg.g(
    string.concat(svg.prop("filter", "url(#filter)"), svg.prop("fill", "none"), svg.prop("stroke", string.concat("#ff", colors[0])), svg.prop("stroke-width", "140%"), svg.prop("stroke-dasharray", "99")),
    string.concat(
      svg.circle(
        string.concat(svg.prop("id", "c"), svg.prop("cx", "50%"), svg.prop("cy", "50%"), svg.prop("r", "70%"), svg.prop("style", "transform-origin: center")),
        svg.animateTransform(
          string.concat(
            svg.prop("attributeName", "transform"),
            svg.prop("attributeType", "XML"),
            svg.prop("type", "rotate"),
            svg.prop("from", "0 0 0"),
            svg.prop("to", "360 0 0"),
            svg.prop("dur", "120s"),
            svg.prop("repeatCount", "indefinite")
          )
        )
      ),
      string.concat(
        svg.el("use", string.concat(svg.prop("href", "#c"), svg.prop("stroke", string.concat("#", colors[1])), svg.prop("stroke-dasharray", "99 60"))),
        svg.el("use", string.concat(svg.prop("href", "#c"), svg.prop("stroke", string.concat("#", colors[2])), svg.prop("stroke-dasharray", "99 120"))),
        svg.el("use", string.concat(svg.prop("href", "#c"), svg.prop("stroke", string.concat("#", colors[3])), svg.prop("stroke-dasharray", "99 180"))),
        svg.el("use", string.concat(svg.prop("href", "#c"), svg.prop("stroke", string.concat("#", colors[4])), svg.prop("stroke-dasharray", "99 240"))),
        svg.el("use", string.concat(svg.prop("href", "#c"), svg.prop("stroke", string.concat("#", colors[5])), svg.prop("stroke-dasharray", "99 300"))),
        svg.el("use", string.concat(svg.prop("href", "#c"), svg.prop("stroke", string.concat("#", colors[6])), svg.prop("stroke-dasharray", "99 360")))
      )
    )
  ),
  "</svg>"
);

Becomes this:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" height="100%" width="100%">
  <script xmlns="" type="text/javascript"/>
  <filter id="filter">
    <feTurbulence type="fractalNoise" baseFrequency="0.01" numOctaves="3" seed="50"/>
    <feDisplacementMap in="SourceGraphic" yChannelSelector="R" scale="99"/>
  </filter>
  <rect width="100%" height="100%" fill="#F2F3F5"/>
  <g filter="url(#filter)" fill="none" stroke="#ffff7bcf" stroke-width="140%" stroke-dasharray="99">
    <circle id="c" cx="50%" cy="50%" r="70%" style="transform-origin: center">
      <animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0 0 0" to="360 0 0" dur="500s" repeatCount="indefinite"/>
    </circle>
    <use href="#c" stroke="#484bd0" stroke-dasharray="99 60"/>
    <use href="#c" stroke="#7f0dbd" stroke-dasharray="99 120"/>
    <use href="#c" stroke="#ae3999" stroke-dasharray="99 180"/>
    <use href="#c" stroke="#14baee" stroke-dasharray="99 240"/>
    <use href="#c" stroke="#16d405" stroke-dasharray="99 300"/>
    <use href="#c" stroke="#a8b272" stroke-dasharray="99 360"/>
  </g>
</svg>