|
| 1 | +# Application Binary Interface (ABI) Contract Generator |
| 2 | + |
| 3 | +abi2ruby - generate ready-to-use (blockchain) contract services / function calls for ethereum & co. via application binary inferfaces (abis) |
| 4 | + |
| 5 | + |
| 6 | +* home :: [github.com/rubycocos/blockchain](https://github.com/rubycocos/blockchain) |
| 7 | +* bugs :: [github.com/rubycocos/blockchain/issues](https://github.com/rubycocos/blockchain/issues) |
| 8 | +* gem :: [rubygems.org/gems/abi2ruby](https://rubygems.org/gems/abi2ruby) |
| 9 | +* rdoc :: [rubydoc.info/gems/abi2ruby](http://rubydoc.info/gems/abi2ruby) |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +## Usage |
| 14 | + |
| 15 | +Let's try to generate the contract "wrapper" code in ruby |
| 16 | +from the application binary interface (abi) in json |
| 17 | +for punk blocks (anno 2020) - plus let's add the optional "natspec" comments: |
| 18 | + |
| 19 | +``` ruby |
| 20 | +require 'abi2ruby' |
| 21 | + |
| 22 | +punk_blocks = '0x58e90596c2065befd3060767736c829c18f3474c' |
| 23 | + |
| 24 | +abi = ABI.read( "./abis/#{punk_blocks}.json" ) |
| 25 | +natspec = Natspec.read( "./abis/#{punk_blocks}.md" ) |
| 26 | + |
| 27 | +buf = abi.generate_code( name: 'PunkBlocks', |
| 28 | + address: punk_blocks, |
| 29 | + natspec: natspec ) |
| 30 | +write_text( "./punk_blocks.rb", buf ) |
| 31 | +``` |
| 32 | + |
| 33 | +resulting in: |
| 34 | + |
| 35 | + |
| 36 | +--- |
| 37 | + |
| 38 | +``` ruby |
| 39 | +######################### |
| 40 | +# PunkBlocks contract / (blockchain) services / function calls |
| 41 | +# auto-generated via abi2ruby (see https://rubygems.org/gems/abi2ruby) on 2023-01-13 15:31:38 UTC |
| 42 | +# - 8 query functions(s) |
| 43 | +# |
| 44 | +# |
| 45 | +# - Author: tycoon.eth, thanks to @geraldb & @samwilsn on Github for inspiration! |
| 46 | +# - Version: v0.0.2 |
| 47 | +# - Pragma: solidity ^0.8.17 |
| 48 | +# |
| 49 | +# |
| 50 | +# ███████████ █████ |
| 51 | +# ░░███░░░░░███ ░░███ |
| 52 | +# ░███ ░███ █████ ████ ████████ ░███ █████ |
| 53 | +# ░██████████ ░░███ ░███ ░░███░░███ ░███░░███ |
| 54 | +# ░███░░░░░░ ░███ ░███ ░███ ░███ ░██████░ |
| 55 | +# ░███ ░███ ░███ ░███ ░███ ░███░░███ |
| 56 | +# █████ ░░████████ ████ █████ ████ █████ |
| 57 | +# ░░░░░ ░░░░░░░░ ░░░░ ░░░░░ ░░░░ ░░░░░ |
| 58 | +# |
| 59 | +# |
| 60 | +# |
| 61 | +# ███████████ ████ █████ |
| 62 | +# ░░███░░░░░███░░███ ░░███ |
| 63 | +# ░███ ░███ ░███ ██████ ██████ ░███ █████ █████ |
| 64 | +# ░██████████ ░███ ███░░███ ███░░███ ░███░░███ ███░░ |
| 65 | +# ░███░░░░░███ ░███ ░███ ░███░███ ░░░ ░██████░ ░░█████ |
| 66 | +# ░███ ░███ ░███ ░███ ░███░███ ███ ░███░░███ ░░░░███ |
| 67 | +# ███████████ █████░░██████ ░░██████ ████ █████ ██████ |
| 68 | +# ░░░░░░░░░░░ ░░░░░ ░░░░░░ ░░░░░░ ░░░░ ░░░░░ ░░░░░░ |
| 69 | +# |
| 70 | +# A Registry of 24x24 png images |
| 71 | +# |
| 72 | +# This contract: |
| 73 | +# |
| 74 | +# 1. Stores all the classic traits of the CryptoPunks in |
| 75 | +# individual png files, 100% on-chain. These are then used as |
| 76 | +# blocks to construct CryptoPunk images. Outputted as SVGs. |
| 77 | +# |
| 78 | +# 2. Any of the 10,000 "classic" CryptoPunks can be generated |
| 79 | +# by supplying desired arguments to a function, such as |
| 80 | +# the id of a punk, or a list of the traits. |
| 81 | +# |
| 82 | +# 3. An unlimited number of new punk images can be generated from |
| 83 | +# the existing classic set of traits, or even from new traits! |
| 84 | +# |
| 85 | +# 4. New traits (blocks) can be added to the contract by |
| 86 | +# registering them with the `registerBlock` function. |
| 87 | +# |
| 88 | +# Further documentation: |
| 89 | +# https://github.com/0xTycoon/punk-blocks |
| 90 | +# |
| 91 | +# |
| 92 | +# |
| 93 | +# **Data Structures** |
| 94 | +# |
| 95 | +# Layer is in the order of rendering |
| 96 | +# |
| 97 | +# enum Layer { |
| 98 | +# Base, // 0 Base is the face. Determines if m or f version will be used... |
| 99 | +# Cheeks, // 1 (Rosy Cheeks) |
| 100 | +# Blemish, // 2 (Mole, Spots) |
| 101 | +# Hair, // 3 (Purple Hair, Shaved Head, Pigtails, ...) |
| 102 | +# Beard, // 4 (Big Beard, Front Beard, Goat, ...) |
| 103 | +# Eyes, // 5 (Clown Eyes Green, Green Eye Shadow, ...) |
| 104 | +# Eyewear, // 6 (VR, 3D Glass, Eye Mask, Regular Shades, Welding Glasses, ...) |
| 105 | +# Nose, // 7 (Clown Nose) |
| 106 | +# Mouth, // 8 (Hot Lipstick, Smile, Buck Teeth, ...) |
| 107 | +# MouthProp, // 9 (Medical Mask, Cigarette, ...) |
| 108 | +# Earring, // 10 (Earring) |
| 109 | +# Headgear, // 11 (Beanie, Fedora, Hoodie, Police Cap, Tiara, Headband, ...) |
| 110 | +# Neck // 12 (Choker, Silver Chain, Gold Chain) |
| 111 | +# } |
| 112 | +# |
| 113 | +# struct Block { |
| 114 | +# Layer layer; // 13 possible layers |
| 115 | +# bytes dataMale; // male version of this attribute |
| 116 | +# bytes dataFemale;// female version of this attribute |
| 117 | +# } |
| 118 | +# |
| 119 | +# |
| 120 | +# **Events** |
| 121 | +# |
| 122 | +# event NewBlock(address, uint256, string) |
| 123 | + |
| 124 | + |
| 125 | +class PunkBlocks < Ethlite::Contract |
| 126 | + |
| 127 | + address "0x58e90596c2065befd3060767736c829c18f3474c" |
| 128 | + |
| 129 | +# storage - mapping(bytes32 => Block) public blocks |
| 130 | +# |
| 131 | +# stores punk attributes as a png |
| 132 | +sig "blocks", inputs: ["bytes32"], outputs: ["uint8","bytes","bytes"] |
| 133 | +def blocks(arg0) |
| 134 | + do_call("blocks", arg0) |
| 135 | +end |
| 136 | + |
| 137 | +# function getBlocks |
| 138 | +# |
| 139 | +# getBlocks returns a sequential list of blocks in a single call |
| 140 | +# @param _fromID is which id to begin from |
| 141 | +# @param _count how many items to retrieve. |
| 142 | +# @return Block[] list of blocks, uint256 next id |
| 143 | +sig "getBlocks", inputs: ["uint256","uint256"], outputs: ["(uint8,bytes,bytes)[]","uint256"] |
| 144 | +def getBlocks(_fromID, _count) |
| 145 | + do_call("getBlocks", _fromID, _count) |
| 146 | +end |
| 147 | + |
| 148 | +# storage - mapping(uint256 => bytes32) public index |
| 149 | +# |
| 150 | +# index of each block by its sequence |
| 151 | +sig "index", inputs: ["uint256"], outputs: ["bytes32"] |
| 152 | +def index(arg0) |
| 153 | + do_call("index", arg0) |
| 154 | +end |
| 155 | + |
| 156 | +# storage - uint256 public nextId |
| 157 | +# |
| 158 | +# next id to use when adding a block |
| 159 | +sig "nextId", outputs: ["uint256"] |
| 160 | +def nextId() |
| 161 | + do_call("nextId") |
| 162 | +end |
| 163 | + |
| 164 | +# function svgFromIDs |
| 165 | +# |
| 166 | +# svgFromIDs returns the svg data as a string |
| 167 | +# e.g. [9,55,99] |
| 168 | +# One of the elements must be must be a layer 0 block. |
| 169 | +# This element decides what version of image to use for the higher layers |
| 170 | +# (dataMale or dataFemale) |
| 171 | +# @param _ids uint256 ids of an attribute, by it's index of creation |
| 172 | +sig "svgFromIDs", inputs: ["uint256[]"], outputs: ["string"] |
| 173 | +def svgFromIDs(_ids) |
| 174 | + do_call("svgFromIDs", _ids) |
| 175 | +end |
| 176 | + |
| 177 | +# function svgFromKeys |
| 178 | +# |
| 179 | +# svgFromKeys returns the svg data as a string |
| 180 | +# @param _attributeKeys a list of attribute names that have been hashed, |
| 181 | +# eg keccak256("Male 1"), keccak256("Goat") |
| 182 | +# must have at least 1 layer 0 attribute (eg. keccak256("Male 1")) which |
| 183 | +# decides what version of image to use for the higher layers |
| 184 | +# (dataMale or dataFemale) |
| 185 | +# e.g. ["0x9039da071f773e85254cbd0f99efa70230c4c11d63fce84323db9eca8e8ef283", |
| 186 | +# "0xd5de5c20969a9e22f93842ca4d65bac0c0387225cee45a944a14f03f9221fd4a"] |
| 187 | +sig "svgFromKeys", inputs: ["bytes32[]"], outputs: ["string"] |
| 188 | +def svgFromKeys(_attributeKeys) |
| 189 | + do_call("svgFromKeys", _attributeKeys) |
| 190 | +end |
| 191 | + |
| 192 | +# function svgFromNames |
| 193 | +# |
| 194 | +# svgFromNames returns the svg data as a string |
| 195 | +# @param _attributeNames a list of attribute names, eg "Male 1", "Goat" |
| 196 | +# must have at least 1 layer 0 attribute (eg. Male, Female, Alien, Ape, Zombie) |
| 197 | +# e.g. ["Male 1","Goat"] |
| 198 | +# Where "Male 1" is a layer 0 attribute, that decides what version of |
| 199 | +# image to use for the higher |
| 200 | +# layers (dataMale or dataFemale) |
| 201 | +sig "svgFromNames", inputs: ["string[]"], outputs: ["string"] |
| 202 | +def svgFromNames(_attributeNames) |
| 203 | + do_call("svgFromNames", _attributeNames) |
| 204 | +end |
| 205 | + |
| 206 | +# function svgFromPunkID |
| 207 | +# |
| 208 | +# svgFromPunkID returns the svg data as a string given a punk id |
| 209 | +# @param _tokenID uint256 IDs a punk id, 0-9999 |
| 210 | +sig "svgFromPunkID", inputs: ["uint256"], outputs: ["string"] |
| 211 | +def svgFromPunkID(_tokenID) |
| 212 | + do_call("svgFromPunkID", _tokenID) |
| 213 | +end |
| 214 | + |
| 215 | +end ## class PunkBlocks |
| 216 | +``` |
| 217 | + |
| 218 | + |
| 219 | +That's it for now. |
| 220 | + |
| 221 | + |
| 222 | +Tip: For some pre-packaged ready-to-use "out-of-the-gem" contracts, |
| 223 | +see [**ethlite-contracts »**](https://github.com/rubycocos/blockchain/tree/master/ethlite-contracts) |
| 224 | + |
| 225 | + |
| 226 | + |
| 227 | + |
| 228 | + |
| 229 | + |
| 230 | +## License |
| 231 | + |
| 232 | +The scripts are dedicated to the public domain. |
| 233 | +Use it as you please with no restrictions whatsoever. |
| 234 | + |
| 235 | + |
| 236 | +## Questions? Comments? |
| 237 | + |
| 238 | + |
| 239 | +Post them on the [D.I.Y. Punk (Pixel) Art reddit](https://old.reddit.com/r/DIYPunkArt). Thanks. |
| 240 | + |
| 241 | + |
0 commit comments