cryptopunks 0.0.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []