cryptopunks 1.0.1 → 1.1.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: 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: