scripty.sol
scripty.sol is a gas-efficient HTML builder tuned for stitching large JS based together.
Documentation
scripty.sol allows you to build HTML files that embed JS that are stored on-chain. Some benefits of using scripty.sol:
- Gas efficient. It utilises
DynamicBuffer
to save huge amount of gas while assembling scripts together. - You can use already deployed storage solutions.
- You can build modular JS based HTML files directly on-chain.
- Supports custom HTML tags and inline contents.
Platforms that use scripty.sol
Projects that use scripty.sol
Installation
Contracts and verified scripts(JS) are published through npm:
npm install scripty.sol --save-dev
Example
The example below generates a simple HTML with fullsize canvas element and a script element that draws a rectangle on the canvas:
// Create head tags
HTMLTag[] memory headTags = new HTMLTag[](1);
headTags[0].tagOpen = "<style>";
headTags[0].tagContent = "html{height:100%}body{min-height:100%;margin:0;padding:0}canvas{padding:0;margin:auto;display:block;position:absolute;top:0;bottom:0;left:0;right:0}";
headTags[0].tagClose = "</style>";
// Create body tags
HTMLTag[] memory bodyTags = new HTMLTag[](2);
bodyTags[0].tagOpen = '<canvas id="myCanvas">';
bodyTags[0].tagClose = "</canvas>";
bodyTags[1].tagContent = 'const canvas=document.getElementById("myCanvas"),ctx=canvas.getContext("2d");ctx.beginPath(),ctx.rect(20,20,150,100),ctx.stroke();';
bodyTags[1].tagType = HTMLTagType.script;
// Create HTML request with head and body tags
HTMLRequest memory headTags;
htmlRequest.headTags = headTags;
htmlRequest.bodyTags = bodyTags;
// Get full HTML string
string memory htmlString = IScriptyBuilderV2(
scriptyBuilderAddress
).getHTMLString(htmlRequest);
HTML file output:
<html>
<head>
<style>
html {
height: 100%
}
body {
min-height: 100%;
margin: 0;
padding: 0
}
canvas {
padding: 0;
margin: auto;
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0
}
</style>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.rect(20, 20, 150, 100);
ctx.stroke();
</script>
</body>
</html>
Deployed Contracts
Ethereum Mainnet
- ScriptyStorageV2 - 0xbD11994aABB55Da86DC246EBB17C1Be0af5b7699
- ScriptyBuilderV2 - 0xD7587F110E08F4D120A231bA97d3B577A81Df022
- ETHFSV2FileStorage - 0x8FAA1AAb9DA8c75917C43Fb24fDdb513edDC3245
Ethereum Goerli
- ScriptyStorageV2 - 0xbD11994aABB55Da86DC246EBB17C1Be0af5b7699
- ScriptyBuilderV2 - 0xD7587F110E08F4D120A231bA97d3B577A81Df022
- ETHFSV2FileStorage - 0x8FAA1AAb9DA8c75917C43Fb24fDdb513edDC3245
Ethereum Sepolia
- ScriptyStorageV2 - 0xbD11994aABB55Da86DC246EBB17C1Be0af5b7699
- ScriptyBuilderV2 - 0xD7587F110E08F4D120A231bA97d3B577A81Df022
- ETHFSV2FileStorage - 0x8FAA1AAb9DA8c75917C43Fb24fDdb513edDC3245
Base contracts
- ScriptyStorageV2 - 0xbD11994aABB55Da86DC246EBB17C1Be0af5b7699
- ScriptyBuilderV2 - 0xD7587F110E08F4D120A231bA97d3B577A81Df022
- ETHFSV2FileStorage - 0x8FAA1AAb9DA8c75917C43Fb24fDdb513edDC3245
Base Sepolia
- ScriptyStorageV2 - 0xbD11994aABB55Da86DC246EBB17C1Be0af5b7699
- ScriptyBuilderV2 - 0xD7587F110E08F4D120A231bA97d3B577A81Df022
- ETHFSV2FileStorage - 0x8FAA1AAb9DA8c75917C43Fb24fDdb513edDC3245
Optimism
- ScriptyStorageV2 - 0xbD11994aABB55Da86DC246EBB17C1Be0af5b7699
- ScriptyBuilderV2 - 0xD7587F110E08F4D120A231bA97d3B577A81Df022
- ETHFSV2FileStorage - 0x8FAA1AAb9DA8c75917C43Fb24fDdb513edDC3245
Optimism Sepolia
- ScriptyStorageV2 - 0xbD11994aABB55Da86DC246EBB17C1Be0af5b7699
- ScriptyBuilderV2 - 0xD7587F110E08F4D120A231bA97d3B577A81Df022
- ETHFSV2FileStorage - 0x8FAA1AAb9DA8c75917C43Fb24fDdb513edDC3245
Live Examples
NFT1 NFT2
Stacked 3D Objects Shapes -Both NFTs assemble PNG compressed base 64 encoded three.js
with an uncompressed demo scene. First NFT creates some 3D cubes. Second NFT gets the first NFT scene on-chain and adds spheres.
p5js from EthFS FileStore V2
Assembles base64 encoded p5.js
that's stored in ethfs's FileStore contract with a demo scene. Metadata and animation URL are both base64 encoded.
p5js from EthFS FileStore V2 - URL Safe
Assembles base64 encoded p5.js
that's stored in ethfs's FileStore contract with a demo scene. Metadata and animation URL are both URL encoded.
Random Shapes
Assembles multiple uncompressed scripts that draw shapes on same <canvas></canvas>
element with a controller script that is created in NFT contract. This controller script passes some chain parameters to canvas scene.
Cube3D - GZIP Compressed - BASE64 Encoded
Assembles GZIP compressed Base64 encoded three.js
with a demo scene. Metadata and animation URL are both base64 encoded.
Cube3D - GZIP Compressed - URL Safe
Assembles GZIP compressed base64 encoded three.js
with a demo scene. Metadata and animation URL are both URL encoded.
Cube3D - PNG Compressed - URL Safe
Assembles PNG compressed base64 encoded three.js
with a demo scene. Metadata and animation URL are both URL encoded.
Cube3D - PNG Compressed - URL Safe with custom wrap
Assembles PNG compressed base64 encoded three.js
with a demo scene. Metadata and animation URL are both URL encoded. It uses custom script wraps.
ThreeJS Module - GZIP Compressed - URL Safe with custom wrap
Assembles GZIP compressed base64 encoded modular three.js
with a demo scene. Metadata and animation URL are both URL encoded. It uses custom script wraps. This is the most complex of all the examples. It demonstrates how to:
- dynamically inject data into your javascript code
- load gzipped javascript modules in the desired order, using gzipped es-module-shim for full browser support
- embed custom javascript
- make it all URL safe