abigen 0.0.1 → 0.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 +4 -4
- data/README.md +211 -1
- data/Rakefile +9 -1
- data/lib/abigen.rb +44 -14
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 961de95760c3dc2b5b3f6c6eafc2e95bd10848a4d3a395256e85038dec22638e
|
4
|
+
data.tar.gz: 4bfc9edef80e2ffc854a9f81a9dae1a59d40554e5e44983cff827a74734dba07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
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',
|
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 << "#
|
18
|
-
buf << "#
|
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.
|
38
|
-
|
39
|
-
|
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
|
-
|
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
|
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-
|
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
|