cryptopunks 1.0.1 → 1.1.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: 24d517bf83d2656a15cbc77b08adb64d35a00b9e0a411fc9627dc4a450d2360a
4
- data.tar.gz: 96fcc259d4d1a595d393f4ec197fb6262837fd73d3541aa682c27cb76f7a6606
3
+ metadata.gz: db4841328c13e863838826b922663aef0e8e28d3f1b2f551e18e95fc4b8cc81b
4
+ data.tar.gz: 0f1d9bb17816c0e7152c3a4fb403927aa5219528fa41931fb9fbcf23303a11e7
5
5
  SHA512:
6
- metadata.gz: 8b9d6ec35fa3714317c62da3eadd38a8a4f042e1212cafddc2c1865aee8d3139648f39cc9c371c13f4c393ab56585a5f891a9ba6513ad6a1f3aaaded1920baba
7
- data.tar.gz: 390e02ed6f649056f4b4a8a2797ce58626161f8d9e7b6e3b46ae8dab5dcbf9e34c685a574e54c5d4d1634f18264a9000bb0ff6cafa2d470ba1572d6e11530ec3
6
+ metadata.gz: c73e7546c178138a62d8b39b4624a85f638ec18c1268537a0b198cf317b6200272c1506f7d0943f6b45594aa81af2fa7d8b628f67c851cabff854a659f65a190
7
+ data.tar.gz: 513e3f4bfd838d7e57f24c6005e6161e1a4eeecdc46c6493deb06234105678c5ce7db70fac44226c948038257d443642f1c542f2de18e4e02a9bc0309642a157
data/Manifest.txt CHANGED
@@ -5,4 +5,8 @@ Rakefile
5
5
  bin/cryptopunk
6
6
  bin/punk
7
7
  lib/cryptopunks.rb
8
+ lib/cryptopunks/attributes.rb
9
+ lib/cryptopunks/dataset.rb
10
+ lib/cryptopunks/image.rb
11
+ lib/cryptopunks/structs.rb
8
12
  lib/cryptopunks/version.rb
data/README.md CHANGED
@@ -8,44 +8,10 @@ cryptopunks - mint your own 24×24 pixel punk images off chain from the True Off
8
8
  * rdoc :: [rubydoc.info/gems/cryptopunks](http://rubydoc.info/gems/cryptopunks)
9
9
 
10
10
 
11
-
12
- > Someday, owning a CryptoPunk might signify just how early of an
13
- > adopter you were into the world of blockchain and its thriving digital
14
- > art scene. Or, they could just be a bunch of [24×24 pixel] images.
15
- >
16
- > -- [June 2017](https://mashable.com/2017/06/16/cryptopunks-ethereum-art-collectibles/)
17
- >
18
- >
19
- > There will be a desire and need to buy expensive [status symbols]
20
- > in the digital realm [to "flex" how rich I am].
21
- > What could be more desirable than a small [24×24]
22
- > pixelated [knitted cap-wearing ape] face?
23
- > CryptoPunk artwork [![](i/punk-8219.png) [#8219](https://www.larvalabs.com/cryptopunks/details/8219)] just sold for $176,000.
24
- >
25
- > -- [January 2021](https://decrypt.co/53519/an-ethereum-based-cryptopunk-artwork-just-sold-for-176000)
26
- >
27
- >
28
- > Ultra-rare alien [24×24 pixel] CryptoPunk
29
- > sells for 605 ETH, or $750,000.
30
- > The investment thesis. "Aliens are the rarest form of CryptoPunk and
31
- > we believe that the acquired Alien [![](i/punk-2890.png) [#2890](https://www.larvalabs.com/cryptopunks/details/2890), one of nine]
32
- > will be prized by collectors over
33
- > time and mature into an iconic digital art piece."
34
- >
35
- > -- [January 2021](https://cointelegraph.com/news/ultra-rare-alien-cryptopunk-nft-sells-for-605-eth-or-750-000)
36
- >
37
- >
38
- > The [CryptoPunksMarket] contract now holds 4,095 ETH (~$5.4M USD) in open bids and pending withdrawals.
39
- >
40
- > -- [January 2021](https://twitter.com/larvalabs/status/1353915659453870080)
41
-
42
-
43
-
44
11
  New to Crypto Punks?
45
12
  See the [**Awesome CryptoPunks Bubble (Anno 2021) - Modern 24×24 Pixel Crypto Art on the Blockchain** »](https://github.com/openblockchains/awesome-cryptopunks-bubble)
46
13
 
47
14
 
48
-
49
15
  ## Command Line
50
16
 
51
17
  Use the `punk` (or `cryptopunk`) command line tool. Try:
@@ -196,5 +162,4 @@ Use it as you please with no restrictions whatsoever.
196
162
 
197
163
  ## Questions? Comments?
198
164
 
199
- Send them along to the [wwwmake forum](http://groups.google.com/group/wwwmake).
200
- Thanks!
165
+ Post them on the [cryptopunk reddit](https://www.reddit.com/r/cryptopunk). Thanks.
data/Rakefile CHANGED
@@ -20,6 +20,7 @@ Hoe.spec 'cryptopunks' do
20
20
  self.extra_deps = [
21
21
  ['crypto-lite'],
22
22
  ['chunky_png'],
23
+ ['csvreader'],
23
24
  ]
24
25
 
25
26
  self.licenses = ['Public Domain']
data/lib/cryptopunks.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  ## 3rd party
2
2
  require 'crypto-lite'
3
3
  require 'chunky_png'
4
+ require 'csvreader'
5
+
4
6
 
5
7
  ## extra stdlibs
6
8
  require 'fileutils'
@@ -10,94 +12,14 @@ require 'optparse'
10
12
 
11
13
  ## our own code
12
14
  require 'cryptopunks/version' # note: let version always go first
13
-
14
-
15
- module Cryptopunks
16
- class Image
17
- def self.read( path='./punks.png' )
18
- data = File.open( path, 'rb' ) { |f| f.read }
19
- new( data )
20
- end
21
-
22
-
23
- attr_accessor :zoom
24
-
25
- PUNK_ROWS = 100
26
- PUNK_COLS = 100
27
- PUNK_COUNT = PUNK_ROWS * PUNK_COLS ## 10_000 = 100x100 (24000x24000 pixel)
28
-
29
- PUNK_HEIGHT = 24
30
- PUNK_WIDTH = 24
31
-
32
- PUNK_HASH = 'ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b'
33
-
34
-
35
- def initialize( data )
36
- @punks = ChunkyPNG::Image.from_blob( data )
37
- puts " #{@punks.height}x#{@punks.width} (height x width)"
38
-
39
- ## check sha256 checksum
40
- @hexdigest = sha256( data )
41
- if original?
42
- puts " >#{@hexdigest}< SHA256 hash matching"
43
- puts " ✓ True Official Genuine CryptoPunks™ verified"
44
- else
45
- puts " !! ERROR: >#{hexdigest}< SHA256 hash NOT matching"
46
- puts " >#{PUNK_HASH}< expected for True Official Genuine CryptoPunks™."
47
- puts ""
48
- puts " Sorry, please download the original."
49
- exit 1
50
- end
51
-
52
- @zoom = 1
53
- end
54
-
55
-
56
- def hexdigest() @hexdigest end
57
-
58
- def verify?() @hexdigest == PUNK_HASH; end
59
- alias_method :genuine?, :verify?
60
- alias_method :original?, :verify?
61
-
62
-
63
-
64
- def size() PUNK_COUNT; end
65
-
66
- def []( index )
67
- @zoom == 1 ? crop( index ) : scale( index, @zoom )
68
- end
69
-
70
-
71
- def crop( index )
72
- y, x = index.divmod( PUNK_ROWS )
73
- @punks.crop( x*PUNK_WIDTH, y*PUNK_HEIGHT, PUNK_WIDTH, PUNK_HEIGHT )
74
- end
75
-
76
-
77
- def scale( index, zoom )
78
- punk = ChunkyPNG::Image.new( PUNK_WIDTH*zoom, PUNK_HEIGHT*zoom,
79
- ChunkyPNG::Color::WHITE )
80
-
81
- ## (x,y) offset in big all-in-one punks image
82
- y, x = index.divmod( PUNK_ROWS )
83
-
84
- ## copy all 24x24 pixels
85
- PUNK_WIDTH.times do |i|
86
- PUNK_HEIGHT.times do |j|
87
- pixel = @punks[i+x*PUNK_WIDTH, j+y*PUNK_HEIGHT]
88
- zoom.times do |n|
89
- zoom.times do |m|
90
- punk[n+zoom*i,m+zoom*j] = pixel
91
- end
92
- end
93
- end
94
- end
95
- punk
96
- end
97
- end ## class Image
15
+ require 'cryptopunks/attributes'
16
+ require 'cryptopunks/structs'
17
+ require 'cryptopunks/image'
18
+ require 'cryptopunks/dataset'
98
19
 
99
20
 
100
21
 
22
+ module Cryptopunks
101
23
  class Tool
102
24
  def run( args )
103
25
  opts = { zoom: 1,
@@ -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,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,84 @@
1
+ module Cryptopunks
2
+ class Image
3
+ def self.read( path='./punks.png' )
4
+ data = File.open( path, 'rb' ) { |f| f.read }
5
+ new( data )
6
+ end
7
+
8
+
9
+ attr_accessor :zoom
10
+
11
+ PUNK_ROWS = 100
12
+ PUNK_COLS = 100
13
+ PUNK_COUNT = PUNK_ROWS * PUNK_COLS ## 10_000 = 100x100 (24000x24000 pixel)
14
+
15
+ PUNK_HEIGHT = 24
16
+ PUNK_WIDTH = 24
17
+
18
+ PUNK_HASH = 'ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b'
19
+
20
+
21
+ def initialize( data )
22
+ @punks = ChunkyPNG::Image.from_blob( data )
23
+ puts " #{@punks.height}x#{@punks.width} (height x width)"
24
+
25
+ ## check sha256 checksum
26
+ @hexdigest = sha256( data )
27
+ if original?
28
+ puts " >#{@hexdigest}< SHA256 hash matching"
29
+ puts " ✓ True Official Genuine CryptoPunks™ verified"
30
+ else
31
+ puts " !! ERROR: >#{hexdigest}< SHA256 hash NOT matching"
32
+ puts " >#{PUNK_HASH}< expected for True Official Genuine CryptoPunks™."
33
+ puts ""
34
+ puts " Sorry, please download the original."
35
+ exit 1
36
+ end
37
+
38
+ @zoom = 1
39
+ end
40
+
41
+
42
+ def hexdigest() @hexdigest end
43
+
44
+ def verify?() @hexdigest == PUNK_HASH; end
45
+ alias_method :genuine?, :verify?
46
+ alias_method :original?, :verify?
47
+
48
+
49
+
50
+ def size() PUNK_COUNT; end
51
+
52
+ def []( index )
53
+ @zoom == 1 ? crop( index ) : scale( index, @zoom )
54
+ end
55
+
56
+
57
+ def crop( index )
58
+ y, x = index.divmod( PUNK_ROWS )
59
+ @punks.crop( x*PUNK_WIDTH, y*PUNK_HEIGHT, PUNK_WIDTH, PUNK_HEIGHT )
60
+ end
61
+
62
+
63
+ def scale( index, zoom )
64
+ punk = ChunkyPNG::Image.new( PUNK_WIDTH*zoom, PUNK_HEIGHT*zoom,
65
+ ChunkyPNG::Color::WHITE )
66
+
67
+ ## (x,y) offset in big all-in-one punks image
68
+ y, x = index.divmod( PUNK_ROWS )
69
+
70
+ ## copy all 24x24 pixels
71
+ PUNK_WIDTH.times do |i|
72
+ PUNK_HEIGHT.times do |j|
73
+ pixel = @punks[i+x*PUNK_WIDTH, j+y*PUNK_HEIGHT]
74
+ zoom.times do |n|
75
+ zoom.times do |m|
76
+ punk[n+zoom*i,m+zoom*j] = pixel
77
+ end
78
+ end
79
+ end
80
+ end
81
+ punk
82
+ end
83
+ end ## class Image
84
+ end ## module Cryptopunks
@@ -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
@@ -3,8 +3,8 @@
3
3
  module Cryptopunks
4
4
 
5
5
  MAJOR = 1
6
- MINOR = 0
7
- PATCH = 1
6
+ MINOR = 1
7
+ PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cryptopunks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.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-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: crypto-lite
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: csvreader
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rdoc
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -92,6 +106,10 @@ files:
92
106
  - bin/cryptopunk
93
107
  - bin/punk
94
108
  - lib/cryptopunks.rb
109
+ - lib/cryptopunks/attributes.rb
110
+ - lib/cryptopunks/dataset.rb
111
+ - lib/cryptopunks/image.rb
112
+ - lib/cryptopunks/structs.rb
95
113
  - lib/cryptopunks/version.rb
96
114
  homepage: https://github.com/rubycoco/blockchain
97
115
  licenses: