abigen 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +211 -1
  3. data/Rakefile +9 -1
  4. data/lib/abigen.rb +44 -14
  5. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2af88adfb037b066adbcdb376f41d9c7b22f90ac72832ed0804b6f14de2964e3
4
- data.tar.gz: f95aee9a46c98b9896d9c9c09587ddfe55b1ac1b81d4e6d1a9905b07b5e5d9a5
3
+ metadata.gz: 961de95760c3dc2b5b3f6c6eafc2e95bd10848a4d3a395256e85038dec22638e
4
+ data.tar.gz: 4bfc9edef80e2ffc854a9f81a9dae1a59d40554e5e44983cff827a74734dba07
5
5
  SHA512:
6
- metadata.gz: 3395ab689b6efc2b354287940f376567c5b7c0e34e6693662931150a7c19da0768c377ab1187a82563a5d33f667c1684d4aedc720b9a7da0fdfed484a5b33097
7
- data.tar.gz: 470b580d57671302f73b10abaebf83e1519096c6e93d4843626160a30b4dd268ad4f45c8ff5f9e895eb48f9973955e72ced6b434745e7027a0bc884f9bb0626f
6
+ metadata.gz: 9c9e9d95d7f029bb08cf58c93ff0c2fd7b7b1a0808086283b090484ae4fc182c81ca0cba26b1a9c78a294eb84f019d9a6f23022eb0b36b1ef78dd88617b5877b
7
+ data.tar.gz: c4535d75a502ea5a8a425328008bc1552e156dd33470546bb21c392ec5661f5fd3138574ad9c5e88c5cccb028899a4723a77470d39050e70aa638b9b8f9fdb73
data/README.md CHANGED
@@ -12,7 +12,217 @@ abigen - generate ready-to-use (blockchain) contract services / function calls f
12
12
 
13
13
  ## Usage
14
14
 
15
- To be done
15
+ Let's try to generate the contract "wrapper" code in ruby
16
+ from the application binary interface (abi) in json
17
+ for punk blocks (anno 2020) - plus let's add the optional "natspec" comments:
18
+
19
+ ``` ruby
20
+ require 'abigen'
21
+
22
+ punk_blocks = '0x58e90596c2065befd3060767736c829c18f3474c'
23
+
24
+ abi = ABI.read( "./abis/#{punk_blocks}.json" )
25
+ natspec = Natspec.read( "./abis/#{punk_blocks}.md" )
26
+
27
+ buf = abi.generate_code( name: 'PunkBlocks',
28
+ address: punk_blocks,
29
+ natspec: natspec )
30
+ write_text( "./punk_blocks.rb", buf )
31
+ ```
32
+
33
+ resulting in:
34
+
35
+
36
+ ---
37
+
38
+ ``` ruby
39
+ #########################
40
+ # PunkBlocks contract / (blockchain) services / function calls
41
+ # auto-generated via abigen (see https://rubygems.org/gems/abigen) on 2023-01-13 15:31:38 UTC
42
+ # - 8 query functions(s)
43
+ #
44
+ #
45
+ # - Author: tycoon.eth, thanks to @geraldb & @samwilsn on Github for inspiration!
46
+ # - Version: v0.0.2
47
+ # - Pragma: solidity ^0.8.17
48
+ #
49
+ #
50
+ # ███████████ █████
51
+ # ░░███░░░░░███ ░░███
52
+ # ░███ ░███ █████ ████ ████████ ░███ █████
53
+ # ░██████████ ░░███ ░███ ░░███░░███ ░███░░███
54
+ # ░███░░░░░░ ░███ ░███ ░███ ░███ ░██████░
55
+ # ░███ ░███ ░███ ░███ ░███ ░███░░███
56
+ # █████ ░░████████ ████ █████ ████ █████
57
+ # ░░░░░ ░░░░░░░░ ░░░░ ░░░░░ ░░░░ ░░░░░
58
+ #
59
+ #
60
+ #
61
+ # ███████████ ████ █████
62
+ # ░░███░░░░░███░░███ ░░███
63
+ # ░███ ░███ ░███ ██████ ██████ ░███ █████ █████
64
+ # ░██████████ ░███ ███░░███ ███░░███ ░███░░███ ███░░
65
+ # ░███░░░░░███ ░███ ░███ ░███░███ ░░░ ░██████░ ░░█████
66
+ # ░███ ░███ ░███ ░███ ░███░███ ███ ░███░░███ ░░░░███
67
+ # ███████████ █████░░██████ ░░██████ ████ █████ ██████
68
+ # ░░░░░░░░░░░ ░░░░░ ░░░░░░ ░░░░░░ ░░░░ ░░░░░ ░░░░░░
69
+ #
70
+ # A Registry of 24x24 png images
71
+ #
72
+ # This contract:
73
+ #
74
+ # 1. Stores all the classic traits of the CryptoPunks in
75
+ # individual png files, 100% on-chain. These are then used as
76
+ # blocks to construct CryptoPunk images. Outputted as SVGs.
77
+ #
78
+ # 2. Any of the 10,000 "classic" CryptoPunks can be generated
79
+ # by supplying desired arguments to a function, such as
80
+ # the id of a punk, or a list of the traits.
81
+ #
82
+ # 3. An unlimited number of new punk images can be generated from
83
+ # the existing classic set of traits, or even from new traits!
84
+ #
85
+ # 4. New traits (blocks) can be added to the contract by
86
+ # registering them with the `registerBlock` function.
87
+ #
88
+ # Further documentation:
89
+ # https://github.com/0xTycoon/punk-blocks
90
+ #
91
+ #
92
+ #
93
+ # **Data Structures**
94
+ #
95
+ # Layer is in the order of rendering
96
+ #
97
+ # enum Layer {
98
+ # Base, // 0 Base is the face. Determines if m or f version will be used to render the remaining layers
99
+ # Cheeks, // 1 (Rosy Cheeks)
100
+ # Blemish, // 2 (Mole, Spots)
101
+ # Hair, // 3 (Purple Hair, Shaved Head, Pigtails, ...)
102
+ # Beard, // 4 (Big Beard, Front Beard, Goat, ...)
103
+ # Eyes, // 5 (Clown Eyes Green, Green Eye Shadow, ...)
104
+ # Eyewear, // 6 (VR, 3D Glass, Eye Mask, Regular Shades, Welding Glasses, ...)
105
+ # Nose, // 7 (Clown Nose)
106
+ # Mouth, // 8 (Hot Lipstick, Smile, Buck Teeth, ...)
107
+ # MouthProp, // 9 (Medical Mask, Cigarette, ...)
108
+ # Earring, // 10 (Earring)
109
+ # Headgear, // 11 (Beanie, Fedora, Hoodie, Police Cap, Tiara, Headband, ...)
110
+ # Neck // 12 (Choker, Silver Chain, Gold Chain)
111
+ # }
112
+ #
113
+ # struct Block {
114
+ # Layer layer; // 13 possible layers
115
+ # bytes dataMale; // male version of this attribute
116
+ # bytes dataFemale;// female version of this attribute
117
+ # }
118
+ #
119
+ #
120
+ # **Events**
121
+ #
122
+ # event NewBlock(address, uint256, string)
123
+
124
+
125
+ class PunkBlocks < Ethlite::Contract
126
+
127
+ address "0x58e90596c2065befd3060767736c829c18f3474c"
128
+
129
+ # storage - mapping(bytes32 => Block) public blocks
130
+ #
131
+ # stores punk attributes as a png
132
+ sig "blocks", inputs: ["bytes32"], outputs: ["uint8","bytes","bytes"]
133
+ def blocks(arg0)
134
+ do_call("blocks", arg0)
135
+ end
136
+
137
+ # function getBlocks
138
+ #
139
+ # getBlocks returns a sequential list of blocks in a single call
140
+ # @param _fromID is which id to begin from
141
+ # @param _count how many items to retrieve.
142
+ # @return Block[] list of blocks, uint256 next id
143
+ sig "getBlocks", inputs: ["uint256","uint256"], outputs: ["(uint8,bytes,bytes)[]","uint256"]
144
+ def getBlocks(_fromID, _count)
145
+ do_call("getBlocks", _fromID, _count)
146
+ end
147
+
148
+ # storage - mapping(uint256 => bytes32) public index
149
+ #
150
+ # index of each block by its sequence
151
+ sig "index", inputs: ["uint256"], outputs: ["bytes32"]
152
+ def index(arg0)
153
+ do_call("index", arg0)
154
+ end
155
+
156
+ # storage - uint256 public nextId
157
+ #
158
+ # next id to use when adding a block
159
+ sig "nextId", outputs: ["uint256"]
160
+ def nextId()
161
+ do_call("nextId")
162
+ end
163
+
164
+ # function svgFromIDs
165
+ #
166
+ # svgFromIDs returns the svg data as a string
167
+ # e.g. [9,55,99]
168
+ # One of the elements must be must be a layer 0 block.
169
+ # This element decides what version of image to use for the higher layers
170
+ # (dataMale or dataFemale)
171
+ # @param _ids uint256 ids of an attribute, by it's index of creation
172
+ sig "svgFromIDs", inputs: ["uint256[]"], outputs: ["string"]
173
+ def svgFromIDs(_ids)
174
+ do_call("svgFromIDs", _ids)
175
+ end
176
+
177
+ # function svgFromKeys
178
+ #
179
+ # svgFromKeys returns the svg data as a string
180
+ # @param _attributeKeys a list of attribute names that have been hashed,
181
+ # eg keccak256("Male 1"), keccak256("Goat")
182
+ # must have at least 1 layer 0 attribute (eg. keccak256("Male 1")) which
183
+ # decides what version of image to use for the higher layers
184
+ # (dataMale or dataFemale)
185
+ # e.g. ["0x9039da071f773e85254cbd0f99efa70230c4c11d63fce84323db9eca8e8ef283",
186
+ # "0xd5de5c20969a9e22f93842ca4d65bac0c0387225cee45a944a14f03f9221fd4a"]
187
+ sig "svgFromKeys", inputs: ["bytes32[]"], outputs: ["string"]
188
+ def svgFromKeys(_attributeKeys)
189
+ do_call("svgFromKeys", _attributeKeys)
190
+ end
191
+
192
+ # function svgFromNames
193
+ #
194
+ # svgFromNames returns the svg data as a string
195
+ # @param _attributeNames a list of attribute names, eg "Male 1", "Goat"
196
+ # must have at least 1 layer 0 attribute (eg. Male, Female, Alien, Ape, Zombie)
197
+ # e.g. ["Male 1","Goat"]
198
+ # Where "Male 1" is a layer 0 attribute, that decides what version of
199
+ # image to use for the higher
200
+ # layers (dataMale or dataFemale)
201
+ sig "svgFromNames", inputs: ["string[]"], outputs: ["string"]
202
+ def svgFromNames(_attributeNames)
203
+ do_call("svgFromNames", _attributeNames)
204
+ end
205
+
206
+ # function svgFromPunkID
207
+ #
208
+ # svgFromPunkID returns the svg data as a string given a punk id
209
+ # @param _tokenID uint256 IDs a punk id, 0-9999
210
+ sig "svgFromPunkID", inputs: ["uint256"], outputs: ["string"]
211
+ def svgFromPunkID(_tokenID)
212
+ do_call("svgFromPunkID", _tokenID)
213
+ end
214
+
215
+ end ## class PunkBlocks
216
+ ```
217
+
218
+
219
+ That's it for now.
220
+
221
+
222
+ Tip: For some pre-packaged ready-to-use "out-of-the-gem" contracts,
223
+ see [**ethlite-contracts »**](../ethlite_contracts)
224
+
225
+
16
226
 
17
227
 
18
228
 
data/Rakefile CHANGED
@@ -1,9 +1,16 @@
1
1
  require 'hoe'
2
2
 
3
3
 
4
+ ###
5
+ # hack/ quick fix for broken intuit_values - overwrite with dummy
6
+ class Hoe
7
+ def intuit_values( input ); end
8
+ end
9
+
10
+
4
11
  Hoe.spec 'abigen' do
5
12
 
6
- self.version = '0.0.1'
13
+ self.version = '0.1.0'
7
14
  self.summary = "abigen - generate ready-to-use (blockchain) contract services / function calls for ethereum & co. via application binary inferfaces (abis)"
8
15
  self.description = summary
9
16
 
@@ -18,6 +25,7 @@ Hoe.spec 'abigen' do
18
25
 
19
26
  self.extra_deps = [
20
27
  ['abiparser'],
28
+ ['natspec'],
21
29
  ]
22
30
 
23
31
  self.licenses = ['Public Domain']
data/lib/abigen.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'abiparser'
2
+ require 'natspec'
2
3
 
3
4
 
4
5
  ## our own code
@@ -10,12 +11,23 @@ module ABI
10
11
  class Contract
11
12
 
12
13
 
13
- def generate_code( name: 'Contract', address: nil )
14
+ def generate_code( name: 'Contract',
15
+ address: nil,
16
+ natspec: nil )
14
17
  buf = ''
15
18
  buf << "#########################\n"
16
19
  buf << "# #{name} contract / (blockchain) services / function calls\n"
17
- buf << "# auto-generated via abigen (see https://rubygems.org/gems/abigen) on #{Time.now.utc}\n"
18
- buf << "# - #{query_functions.size} query functions(s)\n\n"
20
+ buf << "# auto-generated via abigen (see https://rubygems.org/gems/abigen) on #{Time.now.utc}\n"
21
+ buf << "# - #{query_functions.size} query functions(s)\n"
22
+
23
+ if natspec && natspec.head.size > 0
24
+ buf << "#\n#\n"
25
+ natspec.head.each do |line|
26
+ buf << (line.empty? ? "#\n" : "# #{line}\n")
27
+ end
28
+ end
29
+ buf << "\n\n"
30
+
19
31
 
20
32
 
21
33
  buf << "class #{name} < Ethlite::Contract\n\n"
@@ -30,20 +42,18 @@ def generate_code( name: 'Contract', address: nil )
30
42
  if query_functions.size > 0
31
43
  buf << "\n"
32
44
  query_functions.each do |func|
33
- buf << "# #{func.doc} _readonly_\n"
34
-
35
- buf << %Q{sig "#{func.name}"}
36
45
 
37
- if func.inputs.size > 0
38
- quoted_types = func.inputs.map {|param| %Q{"#{param.sig}"} }
39
- buf << ", inputs: [#{quoted_types.join(',')}]"
46
+ if natspec && (natspec.storage[ func.name] || natspec.functions[ func.name ])
47
+ sect = natspec.storage[ func.name ] || natspec.functions[ func.name ]
48
+ buf << "# #{sect[0]}\n#\n"
49
+ sect[1].each do |line|
50
+ buf << (line.empty? ? "#\n" : "# #{line}\n")
51
+ end
52
+ else
53
+ buf << "# #{func.doc} _readonly_\n"
40
54
  end
41
55
 
42
- if func.outputs.size > 0
43
- quoted_types = func.outputs.map {|param| %Q{"#{param.sig}"} }
44
- buf << ", outputs: [#{quoted_types.join(',')}]"
45
- end
46
- buf << "\n"
56
+
47
57
 
48
58
  buf << "def #{func.name}("
49
59
 
@@ -73,6 +83,26 @@ def generate_code( name: 'Contract', address: nil )
73
83
  buf << ")\n"
74
84
 
75
85
  buf << "end\n"
86
+
87
+ ## note: quick hack - for rdoc/yard doc generation
88
+ ## move sig method below method
89
+ buf << %Q{sig "#{func.name}"}
90
+
91
+ if func.inputs.size > 0
92
+ quoted_types = func.inputs.map {|param| %Q{"#{param.sig}"} }
93
+ buf << ", inputs: [#{quoted_types.join(',')}]"
94
+ end
95
+
96
+ if func.outputs.size > 0
97
+ quoted_types = func.outputs.map {|param| %Q{"#{param.sig}"} }
98
+ buf << ", outputs: [#{quoted_types.join(',')}]"
99
+ end
100
+ buf << "\n"
101
+
102
+
103
+
104
+
105
+
76
106
  buf << "\n"
77
107
  end
78
108
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abigen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.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: 2023-01-10 00:00:00.000000000 Z
11
+ date: 2023-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: abiparser
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: natspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rdoc
29
43
  requirement: !ruby/object:Gem::Requirement