cryptopunks 0.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92192671eaee8d69d5a4e56b28a6d38d0fd2140739fab1a11053d4f4b2fe82ab
4
- data.tar.gz: 9d803e337667a543a6438f8b22e937153965d31fbb4be8ac2420f9427d2f0710
3
+ metadata.gz: f8f5a03075399de98c5456fd8c74bcd84c2bebea84b033131351c737dd1934ba
4
+ data.tar.gz: cb75041e34f7104b4e19ab9913a66d3383273299f0a2bec10b53d2c6d428f4f0
5
5
  SHA512:
6
- metadata.gz: 374886a9f63aca0c2ff6149b3c8e9ad906555c43fa3a917eb8a6dd6f997bd67a6c419dabd179f0c15b2874e65bd69bf640fbd33dd0654864865a53161265f9bd
7
- data.tar.gz: 9e2942c55b95b628bf1b205405cf203b28f83ae90d0a79cf61feacfa1ec96baa0e95ec4e55deec38a2260209998d6b92bec0255461f469e7318767909170145c
6
+ metadata.gz: 258ce6be66ad8a06dae14aeb916e620549e50e2dc82a3d96964dbd31e7766df5205b89e630cf3c703b2dbbc52d0e14c4314751447e200ceab47fc7d8bbc81891
7
+ data.tar.gz: c5d5556a2a644a25431f666fb46aa667c0460a721e379b43e17284e4400cb3b515e34d10fa28f2105dd0b45ea5c2bb039518bd45cf59aa2e1da8e98be455871e
data/Manifest.txt CHANGED
@@ -2,5 +2,11 @@ CHANGELOG.md
2
2
  Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
+ bin/cryptopunk
6
+ bin/punk
5
7
  lib/cryptopunks.rb
8
+ lib/cryptopunks/attributes.rb
9
+ lib/cryptopunks/composite.rb
10
+ lib/cryptopunks/dataset.rb
11
+ lib/cryptopunks/structs.rb
6
12
  lib/cryptopunks/version.rb
data/README.md CHANGED
@@ -1,13 +1,238 @@
1
- # cryptopunks
1
+ # Crypto Punks
2
2
 
3
- mint your own 24×24 pixel punk images off chain from the True Official Genuine CryptoPunks™ sha256-verified original; incl. 2x/4x/8x zoom for bigger sizes
3
+ cryptopunks - mint your own 24×24 pixel punk images off chain from the True Official Genuine CryptoPunks™ sha256-verified original 10 000 unique character collection; incl. 2x/4x/8x zoom for bigger sizes
4
4
 
5
+ * home :: [github.com/cryptopunksnotdead/cryptopunks](https://github.com/cryptopunksnotdead/cryptopunks)
6
+ * bugs :: [github.com/cryptopunksnotdead/cryptopunks/issues](https://github.com/cryptopunksnotdead/cryptopunks/issues)
7
+ * gem :: [rubygems.org/gems/cryptopunks](https://rubygems.org/gems/cryptopunks)
8
+ * rdoc :: [rubydoc.info/gems/cryptopunks](http://rubydoc.info/gems/cryptopunks)
5
9
 
6
10
 
7
- ## Usage
11
+ New to Crypto Punks?
12
+ See the [**Awesome CryptoPunks Bubble (Anno 2021) - Modern 24×24 Pixel Crypto Art on the Blockchain** »](https://github.com/cryptopunksnotdead/awesome-cryptopunks-bubble)
8
13
 
9
- to be done
10
14
 
15
+ ## Command Line
16
+
17
+ Use the `punk` (or `cryptopunk`) command line tool. Try:
18
+
19
+ ```
20
+ $ punk -h
21
+ ```
22
+
23
+ resulting in:
24
+
25
+ ```
26
+ Usage: cryptopunk [options] IDs
27
+ Mint punk characters from composite (./punks.png) - for IDs use 0 to 9999
28
+
29
+ Options:
30
+ -z, --zoom=ZOOM Zoom factor x2, x4, x8, etc. (default: 1)
31
+ -d, --dir=DIR Output directory (default: .)
32
+ -f, --file=FILE True Official Genuine CryptoPunks™ composite image (default: ./punks.png)
33
+ -h, --help Prints this help
34
+ ```
35
+
36
+
37
+ Step 0 - Download the True Official Genuine CryptoPunks™ composite image
38
+
39
+ One time / first time only - Download the True Official Genuine CryptoPunks™ composite
40
+ housing all 10 000 CryptoPunks
41
+ in a single 2400×2400 image (~830 kb) for free.
42
+ See [`punks.png` »](https://github.com/larvalabs/cryptopunks/blob/master/punks.png)
43
+
44
+
45
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punks-zoom.png)
46
+
47
+
48
+
49
+
50
+ Now let's give it a try. Let's mint punk #0, #2890, and #8219:
51
+
52
+ ```
53
+ $ punk 0 2890 8219
54
+ ```
55
+
56
+ printing:
57
+
58
+ ```
59
+ ==> reading >./punks.png<...
60
+ >ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b< SHA256 hash matching
61
+ ✓ True Official Genuine CryptoPunks™ verified
62
+ ==> (1/3) minting punk #0; writing to >./punk-0000.png<...
63
+ ==> (2/3) minting punk #2890; writing to >./punk-2890.png<...
64
+ ==> (3/3) minting punk #8219; writing to >./punk-8219.png<...
65
+ ```
66
+
67
+ And voila!
68
+
69
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-0000.png)
70
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-2890.png)
71
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-8219.png)
72
+
73
+
74
+
75
+ **Bonus: Try the `-z/--zoom` factor x2, x4, x8, etc.**
76
+
77
+ Let's give it a try. Let's mint punk #0, #2890, and #8219 in 2x format:
78
+
79
+ ```
80
+ $ punk --zoom 2 0 2890 8219
81
+ # -or-
82
+ $ punk -z2 0 2890 8219
83
+ ```
84
+
85
+ printing:
86
+
87
+ ```
88
+ ==> reading >./punks.png<...
89
+ >ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b< SHA256 hash matching
90
+ ✓ True Official Genuine CryptoPunks™ verified
91
+ setting zoom to 2x
92
+ ==> (1/3) minting punk #0; writing to >punk-0000x2.png<...
93
+ ==> (2/3) minting punk #2890; writing to >punk-2890x2.png<...
94
+ ==> (3/3) minting punk #8219; writing to >punk-8219x2.png<...
95
+ ```
96
+
97
+ And voila!
98
+
99
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-0000x2.png)
100
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-2890x2.png)
101
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-8219x2.png)
102
+
103
+ And x4:
104
+
105
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-0000x4.png)
106
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-2890x4.png)
107
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-8219x4.png)
108
+
109
+
110
+ And x8:
111
+
112
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-0000x8.png)
113
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-2890x8.png)
114
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-8219x8.png)
115
+
116
+
117
+ And so on.
118
+
119
+
120
+
121
+
122
+ ## 10 000 More Punks - Unauthorized? No Way?!- Fuck the Establishment - Yes, You Can - Do-It-Yourself - Use Your Own Collections
123
+
124
+
125
+ Use the `-f, --file=FILE` option
126
+ to pass along any unauthorized edition.
127
+ Only make sure all punks are lined-up left-to-right, top-to-bottom
128
+ in the 24x24 pixel format in the composite image.
129
+
130
+
131
+ Let's try the 10 000 More Punks series housing punks in
132
+ packs of a hundred each. Let's have a looksie at the first 100
133
+ in the series.
134
+
135
+
136
+ ![](https://github.com/cryptopunksnotdead/awesome-cryptopunks-bubble/raw/master/i/more-punks-1.png)
137
+
138
+
139
+
140
+ Let's mint punk #0, #19, #50, and #89
141
+ and let's add an offset of 10000
142
+ (to start counting at 10000 instead of 0):
143
+
144
+ ```
145
+ $ punk 0 18 40 88 --file ./more-punks-1.png --offset 10000
146
+ ```
147
+
148
+ printing:
149
+
150
+ ```
151
+ ==> reading >./more-punks-1.png<...
152
+ 240x240 (height x width)
153
+ ==> (1/4) minting punk #10000; writing to >./punk-10000.png<...
154
+ ==> (2/4) minting punk #10018; writing to >./punk-10018.png<...
155
+ ==> (3/4) minting punk #10040; writing to >./punk-10040.png<...
156
+ ==> (4/4) minting punk #10040; writing to >./punk-10088.png<...
157
+ ```
158
+
159
+ And voila!
160
+
161
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10000.png)
162
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10018.png)
163
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10040.png)
164
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10088.png)
165
+
166
+
167
+ And 4x:
168
+
169
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10000x4.png)
170
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10018x4.png)
171
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10040x4.png)
172
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10088x4.png)
173
+
174
+
175
+
176
+
177
+ Let's try the second pack - that is, punks 100 to 199 in the series.
178
+
179
+
180
+ ![](https://github.com/cryptopunksnotdead/awesome-cryptopunks-bubble/raw/master/i/more-punks-2.png)
181
+
182
+
183
+
184
+ Let's mint punk #0, #79, #80, and #90
185
+ and let's add an offset of 10100
186
+ (to start counting at 10000 plus 100 instead of 0):
187
+
188
+ ```
189
+ $ punk 0 79 80 90 --file ./more-punks-2.png --offset 10100
190
+ ```
191
+
192
+ printing:
193
+
194
+ ```
195
+ ==> reading >./more-punks-2.png<...
196
+ 240x240 (height x width)
197
+ ==> (1/4) minting punk #10100; writing to >./punk-10100.png<...
198
+ ==> (2/4) minting punk #10179; writing to >./punk-10179.png<...
199
+ ==> (3/4) minting punk #10180; writing to >./punk-10180.png<...
200
+ ==> (4/4) minting punk #10190; writing to >./punk-10190.png<...
201
+ ```
202
+
203
+ And voila! Super rare - world's first female alien and much more.
204
+
205
+
206
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10100.png)
207
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10179.png)
208
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10180.png)
209
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10190.png)
210
+
211
+
212
+ And 4x:
213
+
214
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10100x4.png)
215
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10179x4.png)
216
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10180x4.png)
217
+ ![](https://github.com/cryptopunksnotdead/cryptopunks/raw/master/cryptopunks/i/punk-10190x4.png)
218
+
219
+
220
+ And so on.
221
+
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+ ## Usage in Your Scripts
230
+
231
+
232
+ Yes, you can mint punks in your own scripts
233
+ and much more.
234
+ See the
235
+ [**Programming CryptoPunks & Copypastas Step-by-Step Booklet / Guide »**](https://github.com/cryptopunksnotdead/programming-cryptopunks)
11
236
 
12
237
 
13
238
 
@@ -26,5 +251,4 @@ Use it as you please with no restrictions whatsoever.
26
251
 
27
252
  ## Questions? Comments?
28
253
 
29
- Send them along to the [wwwmake forum](http://groups.google.com/group/wwwmake).
30
- Thanks!
254
+ Post them on the [CryptoPunksDev reddit](https://old.reddit.com/r/CryptoPunksDev). Thanks.
data/Rakefile CHANGED
@@ -5,10 +5,10 @@ Hoe.spec 'cryptopunks' do
5
5
 
6
6
  self.version = Cryptopunks::VERSION
7
7
 
8
- self.summary = "cryptopunks - mint your own 24×24 pixel punk images off chain from the True Official Genuine CryptoPunks™ sha256-verified original; incl. 2x/4x/8x zoom for bigger sizes"
8
+ self.summary = "cryptopunks - mint your own 24×24 pixel punk images off chain from the True Official Genuine CryptoPunks™ sha256-verified original 10 000 unique character collection; incl. 2x/4x/8x zoom for bigger sizes"
9
9
  self.description = summary
10
10
 
11
- self.urls = { home: 'https://github.com/rubycoco/blockchain' }
11
+ self.urls = { home: 'https://github.com/cryptopunksnotdead/cryptopunks' }
12
12
 
13
13
  self.author = 'Gerald Bauer'
14
14
  self.email = 'wwwmake@googlegroups.com'
@@ -18,8 +18,8 @@ Hoe.spec 'cryptopunks' do
18
18
  self.history_file = 'CHANGELOG.md'
19
19
 
20
20
  self.extra_deps = [
21
- ['crypto-lite'],
22
- ['chunky_png'],
21
+ ['pixelart'],
22
+ ['csvreader'],
23
23
  ]
24
24
 
25
25
  self.licenses = ['Public Domain']
data/bin/cryptopunk ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ###################
4
+ # == DEV TIPS:
5
+ #
6
+ # For local testing run like:
7
+ #
8
+ # ruby -Ilib bin/cryptopunk
9
+ #
10
+ # Set the executable bit in Linux. Example:
11
+ #
12
+ # % chmod a+x bin/cryptopunk
13
+ #
14
+
15
+ require 'cryptopunks'
16
+
17
+ Cryptopunks.main
data/bin/punk ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ###################
4
+ # == DEV TIPS:
5
+ #
6
+ # For local testing run like:
7
+ #
8
+ # ruby -Ilib bin/punk
9
+ #
10
+ # Set the executable bit in Linux. Example:
11
+ #
12
+ # % chmod a+x bin/punk
13
+ #
14
+
15
+ require 'cryptopunks'
16
+
17
+ Cryptopunks.main
data/lib/cryptopunks.rb CHANGED
@@ -1,9 +1,112 @@
1
- require 'pp'
1
+ ## 3rd party
2
+ require 'pixelart'
3
+ require 'csvreader'
4
+
5
+
6
+
7
+ ## extra stdlibs
8
+ require 'digest'
9
+ require 'optparse'
10
+
2
11
 
3
12
 
4
13
  ## our own code
5
14
  require 'cryptopunks/version' # note: let version always go first
15
+ require 'cryptopunks/attributes'
16
+ require 'cryptopunks/structs'
17
+ require 'cryptopunks/composite'
18
+ require 'cryptopunks/dataset'
19
+
20
+
21
+
22
+ module Cryptopunks
23
+ class Tool
24
+ def run( args )
25
+ opts = { zoom: 1,
26
+ outdir: '.',
27
+ file: './punks.png',
28
+ offset: 0,
29
+ }
30
+
31
+ parser = OptionParser.new do |cmd|
32
+ cmd.banner = "Usage: punk (or cryptopunk) [options] IDs"
33
+
34
+ cmd.separator " Mint punk characters from composite (#{opts[:file]}) - for IDs use 0 to 9999"
35
+ cmd.separator ""
36
+ cmd.separator " Options:"
37
+
38
+ cmd.on("-z", "--zoom=ZOOM", "Zoom factor x2, x4, x8, etc. (default: #{opts[:zoom]})", Integer ) do |zoom|
39
+ opts[:zoom] = zoom
40
+ end
41
+
42
+ cmd.on("-d", "--dir=DIR", "Output directory (default: #{opts[:outdir]})", String ) do |outdir|
43
+ opts[:outdir] = outdir
44
+ end
45
+
46
+ cmd.on("-f", "--file=FILE", "True Official Genuine CryptoPunks™ composite image (default: #{opts[:file]})", String ) do |file|
47
+ opts[:file] = file
48
+ end
49
+
50
+ cmd.on("--offset=NUM", "Start counting at offset (default: #{opts[:offset]})", Integer ) do |offset|
51
+ opts[:offset] = offset
52
+ end
53
+
54
+ cmd.on("-h", "--help", "Prints this help") do
55
+ puts cmd
56
+ exit
57
+ end
58
+ end
59
+
60
+ parser.parse!( args )
61
+
62
+ puts "opts:"
63
+ pp opts
64
+
65
+ puts "==> reading >#{opts[:file]}<..."
66
+ punks = Image::Composite.read( opts[:file] )
67
+
68
+
69
+ puts " setting zoom to #{opts[:zoom]}x" if opts[:zoom] != 1
70
+
71
+ ## make sure outdir exits (default is current working dir e.g. .)
72
+ FileUtils.mkdir_p( opts[:outdir] ) unless Dir.exist?( opts[:outdir] )
73
+
74
+ args.each_with_index do |arg,index|
75
+ punk_index = arg.to_i
76
+
77
+ punk = punks[ punk_index ]
78
+
79
+ punk_name = "punk-" + "%04d" % (punk_index + opts[:offset])
80
+
81
+ ## if zoom - add x2,x4 or such
82
+ if opts[:zoom] != 1
83
+ punk = punk.zoom( opts[:zoom] )
84
+ punk_name << "x#{opts[:zoom]}"
85
+ end
86
+
87
+ path = "#{opts[:outdir]}/#{punk_name}.png"
88
+ puts "==> (#{index+1}/#{args.size}) minting punk ##{punk_index+opts[:offset]}; writing to >#{path}<..."
89
+
90
+ punk.save( path )
91
+ end
92
+
93
+ puts "done"
94
+ end ## method run
95
+ end # class Tool
96
+
97
+
98
+ def self.main( args=ARGV )
99
+ Tool.new.run( args )
100
+ end
101
+ end ## module Cryptopunks
102
+
103
+
104
+
105
+ ### add some convenience shortcuts
106
+ CryptoPunks = Cryptopunks
107
+ Punks = Cryptopunks
108
+
109
+
6
110
 
7
111
 
8
- pp Cryptopunks.banner
9
- pp Cryptopunks.root
112
+ puts Cryptopunks.banner # say hello
@@ -0,0 +1,147 @@
1
+ module Cryptopunks
2
+
3
+ ##################
4
+ ## 5 punk types
5
+ TYPES = [
6
+ { name: 'Alien', limit: 9 },
7
+ { name: 'Ape', limit: 24 },
8
+ { name: 'Zombie', limit: 88 },
9
+ { name: 'Female', limit: 3840 },
10
+ { name: 'Male', limit: 6039 },
11
+ ]
12
+
13
+
14
+ ###
15
+ ## categories used from:
16
+ ## https://cryptoslam.io/cryptopunks/checklist
17
+ ## see categories in urls e.g.
18
+ ## - cryptopunks/eyes/horned-rim-glasses
19
+ ## - cryptopunks/hair/peak-spike
20
+ ## - cryptopunks/emotion/smile
21
+ ## - etc.
22
+ ##
23
+
24
+ #######
25
+ ## 87 attributes / accessories
26
+ ##
27
+ ## note: does NOT include 5 punk types (that is, alien, ape, zombie, female, male)
28
+
29
+
30
+ ACCESSORY_TYPES = [
31
+ { name: 'Mouth', accessories: [ { name: 'Cigarette', limit: 961 },
32
+ { name: 'Pipe', limit: 317 },
33
+ { name: 'Vape', limit: 272 },
34
+ { name: 'Medical Mask', limit: 175 }]
35
+ },
36
+ { name: 'Nose', accessories: [ { name: 'Clown Nose', limit: 212 }]
37
+ },
38
+ {
39
+ name: 'Hair',
40
+ accessories: [ { name: 'Wild Blonde', limit: 144 },
41
+ { name: 'Wild Hair', limit: 447 },
42
+ { name: 'Dark Hair', limit: 157 },
43
+ { name: 'Stringy Hair', limit: 463 },
44
+ { name: 'Crazy Hair', limit: 414 },
45
+ { name: 'Messy Hair', limit: 460 },
46
+ { name: 'Mohawk', limit: 441 },
47
+ { name: 'Mohawk Thin', limit: 441 },
48
+ { name: 'Mohawk Dark', limit: 429 },
49
+ { name: 'Peak Spike', limit: 303 },
50
+ { name: 'Frumpy Hair', limit: 442 },
51
+ { name: 'Clown Hair Green', limit: 148 },
52
+ { name: 'Shaved Head', limit: 300 },
53
+ { name: 'Vampire Hair', limit: 147 },
54
+ { name: 'Red Mohawk', limit: 147 },
55
+ { name: 'Blonde Bob', limit: 147 },
56
+ { name: 'Straight Hair Dark', limit: 148 },
57
+ { name: 'Straight Hair', limit: 151 },
58
+ { name: 'Purple Hair', limit: 165 },
59
+ { name: 'Straight Hair Blonde', limit: 144 },
60
+ { name: 'Wild White Hair', limit: 136 },
61
+ { name: 'Half Shaved', limit: 147 },
62
+ { name: 'Pigtails', limit: 94 },
63
+ { name: 'Orange Side', limit: 68 },
64
+ { name: 'Do-rag', limit: 300 },
65
+ { name: 'Tiara', limit: 55 },
66
+ { name: 'Blonde Short', limit: 129 },
67
+ { name: 'Pink With Hat', limit: 95 },
68
+ { name: 'Beanie', limit: 44 },
69
+ { name: 'Headband', limit: 406 },
70
+ { name: 'Bandana', limit: 481 },
71
+ { name: 'Hoodie', limit: 259 },
72
+ { name: 'Top Hat', limit: 115 },
73
+ { name: 'Tassle Hat', limit: 178 },
74
+ { name: 'Cap', limit: 351 },
75
+ { name: 'Knitted Cap', limit: 419 },
76
+ { name: 'Cap Forward', limit: 254 },
77
+ { name: 'Police Cap', limit: 203 },
78
+ { name: 'Fedora', limit: 186 },
79
+ { name: 'Pilot Helmet', limit: 54 },
80
+ { name: 'Cowboy Hat', limit: 142 }]
81
+ },
82
+ {
83
+ name: 'Beard',
84
+ accessories: [{ name: 'Normal Beard', limit: 292 },
85
+ { name: 'Normal Beard Black', limit: 289 },
86
+ { name: 'Front Beard Dark', limit: 260 },
87
+ { name: 'Front Beard', limit: 273 },
88
+ { name: 'Shadow Beard', limit: 526 },
89
+ { name: 'Luxurious Beard', limit: 286 },
90
+ { name: 'Big Beard', limit: 146 },
91
+ { name: 'Chinstrap', limit: 282 },
92
+ { name: 'Mustache', limit: 288 },
93
+ { name: 'Muttonchops', limit: 303 },
94
+ { name: 'Handlebars', limit: 263 },
95
+ { name: 'Goat', limit: 295 }]
96
+ },
97
+ {
98
+ name: 'Ears',
99
+ accessories: [{ name: 'Earring', limit: 2459 }]
100
+ },
101
+ {
102
+ name: 'Eyes',
103
+ accessories: [{ name: 'Blue Eye Shadow', limit: 266 },
104
+ { name: 'Purple Eye Shadow', limit: 262 },
105
+ { name: 'Green Eye Shadow', limit: 271 },
106
+ { name: 'Welding Goggles', limit: 86 },
107
+ { name: 'VR', limit: 332 },
108
+ { name: '3D Glasses', limit: 286 },
109
+ { name: 'Clown Eyes Blue', limit: 384 },
110
+ { name: 'Clown Eyes Green', limit: 382 },
111
+ { name: 'Small Shades', limit: 378 },
112
+ { name: 'Regular Shades', limit: 527 },
113
+ { name: 'Big Shades', limit: 535 },
114
+ { name: 'Classic Shades', limit: 502 },
115
+ { name: 'Nerd Glasses', limit: 572 },
116
+ { name: 'Horned Rim Glasses', limit: 535 },
117
+ { name: 'Eye Mask', limit: 293 },
118
+ { name: 'Eye Patch', limit: 461 }]
119
+ },
120
+ {
121
+ name: 'Lips',
122
+ accessories: [{ name: 'Purple Lipstick', limit: 655 },
123
+ { name: 'Black Lipstick', limit: 617 },
124
+ { name: 'Hot Lipstick', limit: 696 } ]
125
+ },
126
+ {
127
+ name: 'Face',
128
+ accessories: [{ name: 'Spots', limit: 124 },
129
+ { name: 'Mole', limit: 644 }]
130
+ },
131
+ {
132
+ name: 'Neck',
133
+ accessories: [{ name: 'Choker', limit: 48 },
134
+ { name: 'Silver Chain', limit: 156 },
135
+ { name: 'Gold Chain', limit: 169 }]
136
+ },
137
+ { name: 'Cheeks', accessories: [{ name: 'Rosy Cheeks', limit: 128 }]
138
+ },
139
+ { name: 'Teeth', accessories: [{ name: 'Buck Teeth', limit: 78 }]
140
+ },
141
+ { name: 'Emotion', accessories: [{ name: 'Frown', limit: 261 },
142
+ { name: 'Smile', limit: 238 }]
143
+ }
144
+ ]
145
+
146
+
147
+ end # module Cryptopunks
@@ -0,0 +1,62 @@
1
+ module Cryptopunks
2
+ class Image
3
+ class Composite ## nest Composite inside Image - why? why not?
4
+
5
+
6
+ def self.read( path='./punks.png' )
7
+ data = File.open( path, 'rb' ) { |f| f.read }
8
+ new( data )
9
+ end
10
+
11
+
12
+ PUNK_HEIGHT = 24
13
+ PUNK_WIDTH = 24
14
+
15
+ PUNK_HASH = 'ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b'
16
+
17
+
18
+ def initialize( data )
19
+ @punks = ChunkyPNG::Image.from_blob( data )
20
+ puts " #{@punks.height}x#{@punks.width} (height x width)"
21
+
22
+ @punk_rows = @punks.width / PUNK_WIDTH ## e.g. 2400/24 = 100
23
+ @punk_cols = @punks.height / PUNK_HEIGHT ## e.g. 2400/24 = 100
24
+ @punk_count = @punk_rows * @punk_cols ## ## 10000 = 100x100 (2400x2400 pixel)
25
+
26
+ ## check sha256 checksum
27
+ @hexdigest = sha256( data )
28
+ if original?
29
+ puts " >#{@hexdigest}< SHA256 hash matching"
30
+ puts " ✓ True Official Genuine CryptoPunks™ verified"
31
+ end
32
+ end
33
+
34
+
35
+ def sha256( data )
36
+ ## todo/check: or just use Digest::SHA256.hexdigest - why? why not?
37
+ Digest::SHA256.digest( data ).unpack( 'H*' )[0]
38
+ end
39
+
40
+
41
+ def hexdigest() @hexdigest end
42
+
43
+ def verify?() @hexdigest == PUNK_HASH; end
44
+ alias_method :genuine?, :verify?
45
+ alias_method :original?, :verify?
46
+
47
+
48
+
49
+ def size() @punk_count; end
50
+
51
+
52
+ def punk( index )
53
+ y, x = index.divmod( @punk_rows )
54
+ img = @punks.crop( x*PUNK_WIDTH, y*PUNK_HEIGHT, PUNK_WIDTH, PUNK_HEIGHT )
55
+ Pixelart::Image.new( img.width, img.height, img ) ## wrap in pixelart image
56
+ end
57
+ alias_method :[], :punk
58
+
59
+
60
+ end ## class Composite
61
+ end ## class Image
62
+ end ## module Cryptopunks
@@ -0,0 +1,67 @@
1
+
2
+
3
+ module Cryptopunks
4
+ module Dataset
5
+
6
+ def self.read( path='./datasets/punks/*.csv' )
7
+
8
+ datasets = Dir.glob( path )
9
+ #=> ["./datasets/punks/0-999.csv",
10
+ # "./datasets/punks/1000-1999.csv",
11
+ # "./datasets/punks/2000-2999.csv",
12
+ # "./datasets/punks/3000-3999.csv",
13
+ # "./datasets/punks/4000-4999.csv",
14
+ # "./datasets/punks/5000-5999.csv",
15
+ # "./datasets/punks/6000-6999.csv",
16
+ # "./datasets/punks/7000-7999.csv",
17
+ # "./datasets/punks/8000-8999.csv",
18
+ # "./datasets/punks/9000-9999.csv"]
19
+
20
+ rows = []
21
+ datasets.each do |dataset|
22
+ rows += CsvHash.read( dataset )
23
+ end
24
+
25
+ # puts " #{rows.size} rows(s)"
26
+ #=> 10000 rows(s)
27
+
28
+ ### wrap in punk struct for easier access
29
+ punks = []
30
+ rows.each do |row|
31
+ id = row['id'].to_i
32
+ type_q = row['type']
33
+ count = row['count'].to_i
34
+ accessories_q = row['accessories'].split( %r{[ ]*/[ ]*} )
35
+
36
+ if count != accessories_q.size
37
+ puts "!! ERROR - punk data assertion failed - expected accessories count #{count}; got #{accessories_q.size}"
38
+ pp row
39
+ exit 1
40
+ end
41
+
42
+ type = Metadata::Type.find( type_q )
43
+ if type.nil?
44
+ puts "!! ERROR - punk data assertion failed - unknown punk type >#{type_q}<"
45
+ pp row
46
+ exit 1
47
+ end
48
+
49
+ accessories = []
50
+ accessories_q.each do |acc_q|
51
+ acc = Metadata::Accessory.find( acc_q )
52
+ if acc.nil?
53
+ puts "!! ERROR - punk data assertion failed - unknown punk accessory type >#{acc_q}<"
54
+ pp row
55
+ exit 1
56
+ end
57
+ accessories << acc
58
+ end
59
+
60
+ punks << Metadata.new( id, type, accessories )
61
+ end
62
+ punks
63
+ end
64
+ end # module Dataset
65
+ end # module Cryptopunks
66
+
67
+
@@ -0,0 +1,148 @@
1
+
2
+ module Cryptopunks
3
+ ### wrap metadata (e.g. punk types, accessories, etc.
4
+ ## in structs for easy/easier access)
5
+
6
+
7
+
8
+ class Metadata
9
+
10
+ ## nested class
11
+ class Type ## todo/check: use alias family or such?
12
+ attr_reader :name,
13
+ :limit
14
+ def initialize( name, limit )
15
+ @name = name
16
+ @limit = limit
17
+ end
18
+ ## def to_s() @name; end
19
+
20
+ def inspect
21
+ %Q{<Type "#{@name}", limit: #{@limit}>}
22
+ end
23
+
24
+
25
+
26
+ def self.build
27
+ TYPES.reduce( {} ) do |h, rec|
28
+ type = Type.new( rec[:name], rec[:limit ] )
29
+ h[ rec[:name].downcase ] = type
30
+ h
31
+ end
32
+ end
33
+
34
+ def self.registry
35
+ ## auto-build registry (hash table) lookup (by name)
36
+ @@types ||= build
37
+ @@types
38
+ end
39
+
40
+ def self.all() registry.values; end
41
+
42
+ def self.find( q ) registry[ q.to_s.downcase ]; end
43
+ end ## (nested) class Type
44
+
45
+
46
+
47
+ ## nested class
48
+ class AccessoryType
49
+ attr_reader :name,
50
+ :accessories
51
+ def initialize( name, accessories=[] )
52
+ @name = name
53
+ @accessories = accessories
54
+ end
55
+
56
+
57
+
58
+ def self.build
59
+ ACCESSORY_TYPES.reduce( {} ) do |h, rec|
60
+ type = AccessoryType.new( rec[:name] )
61
+ ## add all accessories
62
+ rec[:accessories].each do |rec_acc|
63
+ type.accessories << Accessory.new( rec_acc[:name],
64
+ type,
65
+ rec_acc[:limit].to_i )
66
+ end
67
+ h[ rec[:name].downcase ] = type
68
+ h
69
+ end
70
+ end
71
+
72
+ def self.registry
73
+ ## auto-build registry (hash table) lookup (by name)
74
+ @@types ||= build
75
+ @@types
76
+ end
77
+
78
+ def self.all() registry.values; end
79
+
80
+ def self.find( q ) registry[ q.to_s.downcase ]; end
81
+ end ## (nested) class AccessoryType
82
+
83
+
84
+ ## nested class
85
+ class Accessory
86
+
87
+ attr_reader :name,
88
+ :type,
89
+ :limit
90
+ def initialize( name, type, limit )
91
+ @name = name
92
+ @type = type
93
+ @limit = limit
94
+ end
95
+
96
+
97
+ def inspect
98
+ %Q{<Accessory "#{@name}", type: "#{@type.name}", limit: #{@limit}>}
99
+ end
100
+
101
+
102
+
103
+ def self.build
104
+ AccessoryType.all.reduce( {} ) do |h, type|
105
+ type.accessories.each do |acc|
106
+ h[ acc.name.downcase ] = acc
107
+ end
108
+ h
109
+ end
110
+ end
111
+
112
+ def self.registry
113
+ ## auto-build registry (hash table) lookup (by name)
114
+ @@types ||= build
115
+ @@types
116
+ end
117
+
118
+ def self.all() registry.values; end
119
+
120
+ def self.find( q ) registry[ q.to_s.downcase ]; end
121
+ end ## (nested) class Accessory
122
+
123
+
124
+
125
+
126
+
127
+
128
+ attr_reader :id,
129
+ :type,
130
+ :accessories,
131
+ :birthday ## todo/check: use minted or such?
132
+
133
+ def initialize( id, type, accessories )
134
+ @id = id
135
+ @type = type
136
+ @accessories = accessories
137
+ @birthday = Date.new( 2017, 6, 23) ## all 10,000 minted on June 23, 2017
138
+ end
139
+
140
+ ## convenience helpers for types (5)
141
+ def alien?() @type.name=='Alien'; end
142
+ def ape?() @type.name=='Ape'; end
143
+ def zombie?() @type.name=='Zombie'; end
144
+ def female?() @type.name=='Female'; end
145
+ def male?() @type.name=='Male'; end
146
+ end # class Metadata
147
+
148
+ end # module Cryptopunks
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Cryptopunks
4
4
 
5
- MAJOR = 0
6
- MINOR = 0
7
- PATCH = 1
5
+ MAJOR = 1
6
+ MINOR = 2
7
+ PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cryptopunks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-10 00:00:00.000000000 Z
11
+ date: 2021-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: crypto-lite
14
+ name: pixelart
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: chunky_png
28
+ name: csvreader
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -73,10 +73,12 @@ dependencies:
73
73
  - !ruby/object:Gem::Version
74
74
  version: '3.22'
75
75
  description: cryptopunks - mint your own 24×24 pixel punk images off chain from the
76
- True Official Genuine CryptoPunks™ sha256-verified original; incl. 2x/4x/8x zoom
77
- for bigger sizes
76
+ True Official Genuine CryptoPunks™ sha256-verified original 10 000 unique character
77
+ collection; incl. 2x/4x/8x zoom for bigger sizes
78
78
  email: wwwmake@googlegroups.com
79
- executables: []
79
+ executables:
80
+ - cryptopunk
81
+ - punk
80
82
  extensions: []
81
83
  extra_rdoc_files:
82
84
  - CHANGELOG.md
@@ -87,9 +89,15 @@ files:
87
89
  - Manifest.txt
88
90
  - README.md
89
91
  - Rakefile
92
+ - bin/cryptopunk
93
+ - bin/punk
90
94
  - lib/cryptopunks.rb
95
+ - lib/cryptopunks/attributes.rb
96
+ - lib/cryptopunks/composite.rb
97
+ - lib/cryptopunks/dataset.rb
98
+ - lib/cryptopunks/structs.rb
91
99
  - lib/cryptopunks/version.rb
92
- homepage: https://github.com/rubycoco/blockchain
100
+ homepage: https://github.com/cryptopunksnotdead/cryptopunks
93
101
  licenses:
94
102
  - Public Domain
95
103
  metadata: {}
@@ -114,6 +122,6 @@ rubygems_version: 3.1.4
114
122
  signing_key:
115
123
  specification_version: 4
116
124
  summary: cryptopunks - mint your own 24×24 pixel punk images off chain from the True
117
- Official Genuine CryptoPunks™ sha256-verified original; incl. 2x/4x/8x zoom for
118
- bigger sizes
125
+ Official Genuine CryptoPunks™ sha256-verified original 10 000 unique character collection;
126
+ incl. 2x/4x/8x zoom for bigger sizes
119
127
  test_files: []