solidity 0.1.1 → 0.1.3
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/Manifest.txt +1 -0
- data/README.md +51 -3
- data/Rakefile +9 -0
- data/lib/solidity/parser.rb +173 -0
- data/lib/solidity/version.rb +1 -2
- data/lib/solidity.rb +1 -118
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a34efb053c8fd9211832cedb2a99a05362f10fb3e43323d6bca7cd69783a88d
|
4
|
+
data.tar.gz: 3e113d90344d4a4745836b3b8bea5f18f4ac3c621d56914e5610c331f25dba20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea91690f94b665991f5f2e6934def21c1dd70ac475efc1e6cd578d84a05e31a7437dac0c1c3f9bffecb1283655ba3454d663f04a4ff190246ce240b4ea900535
|
7
|
+
data.tar.gz: f8b3f08e0691d3cfc34b25ab6652a632f41df90a6d0d593f699971886301a329fcb4f6fac048d3d041432d446030b89338cf9cabd01239a00a4a69aa50de9c45
|
data/Manifest.txt
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
|
2
|
+
---
|
3
|
+
|
4
|
+
_The Ruby Programming Language for Contract / Transaction Scripts on the Blockchain World Computer - Yes, It's Just Ruby_
|
5
|
+
|
6
|
+
**sruby - Small, Smart, Secure, Safe, Solid & Sound (S6) Ruby**
|
7
|
+
|
8
|
+
sruby is a subset of mruby that is a subset of "classic" ruby.
|
9
|
+
|
10
|
+
|
11
|
+
For more see the [**Red Paper »**](https://github.com/s6ruby/redpaper)
|
12
|
+
|
13
|
+
---
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
|
1
18
|
# Solidity
|
2
19
|
|
3
20
|
solidity gem - (fuzzy) parser for (crypto) contracts for ethereum & co.
|
@@ -10,6 +27,29 @@ solidity gem - (fuzzy) parser for (crypto) contracts for ethereum & co.
|
|
10
27
|
|
11
28
|
|
12
29
|
|
30
|
+
## New to the Solidity (Contract) Programming Language?
|
31
|
+
|
32
|
+
_Official_
|
33
|
+
|
34
|
+
Solidity Language @ <https://soliditylang.org>
|
35
|
+
|
36
|
+
- Read the Docs @ <https://docs.soliditylang.org/en/latest/>
|
37
|
+
- Blog @ <https://blog.soliditylang.org>
|
38
|
+
- Forum @ <https://forum.soliditylang.org>
|
39
|
+
- Source @ <https://github.com/ethereum/solidity>
|
40
|
+
|
41
|
+
<!-- break -->
|
42
|
+
|
43
|
+
_More_
|
44
|
+
|
45
|
+
Solidity by Example @ <https://solidity-by-example.org>
|
46
|
+
|
47
|
+
Learn X in Y Minutes (Where X=Solidity) @ <https://learnxinyminutes.com/docs/solidity>
|
48
|
+
|
49
|
+
Awesome Solidity @ <https://github.com/bkrem/awesome-solidity>
|
50
|
+
|
51
|
+
|
52
|
+
|
13
53
|
|
14
54
|
|
15
55
|
## Usage
|
@@ -24,9 +64,7 @@ Get / generate outline from source in the solidity (`.sol`) contract programming
|
|
24
64
|
].each do |addr|
|
25
65
|
|
26
66
|
path = "awesome-contracts/address/#{addr}/contract.sol"
|
27
|
-
|
28
|
-
|
29
|
-
parser = Solidity::Parser.new( txt )
|
67
|
+
parser = Solidity::Parser.read( path )
|
30
68
|
|
31
69
|
puts "---"
|
32
70
|
puts "outline:"
|
@@ -67,6 +105,7 @@ library Address
|
|
67
105
|
library Base64
|
68
106
|
abstract contract Context
|
69
107
|
library MerkleProof
|
108
|
+
interface ERC721A__IERC721Receiver
|
70
109
|
contract ERC721A is IERC721A
|
71
110
|
interface IERC721A
|
72
111
|
```
|
@@ -97,6 +136,15 @@ library EnumerableSet
|
|
97
136
|
|
98
137
|
|
99
138
|
|
139
|
+
|
140
|
+
## Bonus: Solidity (Fuzzy) Parser in the Wild / Real-World
|
141
|
+
|
142
|
+
See [**Awesome (Ethereum) Contracts @ Open Blockchains »**](https://github.com/openblockchains/awesome-contracts)
|
143
|
+
|
144
|
+
Add your usage here. Yes, you can.
|
145
|
+
|
146
|
+
|
147
|
+
|
100
148
|
## License
|
101
149
|
|
102
150
|
The `solidity` scripts are dedicated to the public domain.
|
data/Rakefile
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require 'hoe'
|
2
2
|
require './lib/solidity/version.rb'
|
3
3
|
|
4
|
+
|
5
|
+
###
|
6
|
+
# hack/ quick fix for broken intuit_values - overwrite with dummy
|
7
|
+
class Hoe
|
8
|
+
def intuit_values( input ); end
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
|
4
13
|
Hoe.spec 'solidity' do
|
5
14
|
|
6
15
|
self.version = Solidity::VERSION
|
@@ -0,0 +1,173 @@
|
|
1
|
+
module Solidity
|
2
|
+
|
3
|
+
class Parser
|
4
|
+
|
5
|
+
def self.read( path )
|
6
|
+
txt = read_text( path )
|
7
|
+
new( txt )
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
def initialize( txt )
|
13
|
+
@txt = txt
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
###############
|
18
|
+
## quotes
|
19
|
+
##
|
20
|
+
## note: regex pattern \\ needs to get escaped twice, thus, \\.
|
21
|
+
## and for literal \\ use \\\\\.
|
22
|
+
|
23
|
+
## => \\\\. -- allow backslash escapes e.g. \n \t \\ etc.
|
24
|
+
## => [^`] -- everything except backquote
|
25
|
+
|
26
|
+
## todo/fix - check if [^`] includes/matches newline too (yes)? -- add \n for multi-line!
|
27
|
+
|
28
|
+
SINGLE_QUOTE = %r{'
|
29
|
+
( \\\\. | [^'] )*
|
30
|
+
'}x
|
31
|
+
|
32
|
+
DOUBLE_QUOTE = %r{"
|
33
|
+
( \\\\. | [^"] )*
|
34
|
+
"}x
|
35
|
+
|
36
|
+
|
37
|
+
NAME = /[a-zA-Z][a-zA-Z0-9_]*/
|
38
|
+
END_OF_LINE = /\n|$/
|
39
|
+
## inline comments (multi- or end-of-line)
|
40
|
+
END_OF_LINE_OR_COMMENT_OR_KEYWORD_OR_QUOTE = / \n
|
41
|
+
| $
|
42
|
+
| (?=['"])
|
43
|
+
| (?=\/(\/|\*))
|
44
|
+
| (?=\bpragma\b)
|
45
|
+
| (?=\bcontract\b)
|
46
|
+
| (?=\babstract\b)
|
47
|
+
| (?=\blibrary\b)
|
48
|
+
| (?=\binterface\b)
|
49
|
+
/x
|
50
|
+
|
51
|
+
|
52
|
+
def _norm_whitespace( str )
|
53
|
+
## change newlines to spaces and
|
54
|
+
## all multiple spaces to one
|
55
|
+
str = str.gsub( /[ \t\n\r]+/, ' ' )
|
56
|
+
str.strip
|
57
|
+
end
|
58
|
+
|
59
|
+
def _quick_pass_one
|
60
|
+
## note: CANNOT handle inline comments
|
61
|
+
## in pragma, contract, etc. (get "silently" slurped)
|
62
|
+
## report a parse error - if comments slurped - why? why not?
|
63
|
+
##
|
64
|
+
|
65
|
+
|
66
|
+
tree = []
|
67
|
+
|
68
|
+
s = StringScanner.new( @txt )
|
69
|
+
|
70
|
+
loop do
|
71
|
+
s.skip( /[ \t]+/ ) ## note: do NOT skip newlines here; pass along blank/empty lines for now - why? why not?
|
72
|
+
if s.check( "'" ) ## single-quoted string
|
73
|
+
str = s.scan( SINGLE_QUOTE )
|
74
|
+
tree << [:string, str]
|
75
|
+
elsif s.check( '"' ) ## double-quoted string
|
76
|
+
str = s.scan( DOUBLE_QUOTE )
|
77
|
+
tree << [:string, str]
|
78
|
+
elsif s.check( '/*' )
|
79
|
+
comment = s.scan_until( /\*\// )
|
80
|
+
## print "multi-line comment:"
|
81
|
+
## pp comment
|
82
|
+
tree << [:comment, comment]
|
83
|
+
elsif s.check( '//' )
|
84
|
+
comment = s.scan_until( END_OF_LINE ).rstrip
|
85
|
+
## print "comment:"
|
86
|
+
## pp comment
|
87
|
+
tree << [:comment, comment]
|
88
|
+
else
|
89
|
+
name = s.check( NAME )
|
90
|
+
case name
|
91
|
+
when 'pragma'
|
92
|
+
code = s.scan_until( /;/ )
|
93
|
+
code = _norm_whitespace( code )
|
94
|
+
## print "pragma:"
|
95
|
+
## pp code
|
96
|
+
tree << [:pragma, code]
|
97
|
+
when 'contract'
|
98
|
+
code = s.scan_until( /(?=\{)/ )
|
99
|
+
code = _norm_whitespace( code )
|
100
|
+
## print "contract:"
|
101
|
+
## pp code
|
102
|
+
tree << [:contract, code]
|
103
|
+
when 'abstract'
|
104
|
+
code = s.scan_until( /(?=\{)/ )
|
105
|
+
code = _norm_whitespace( code )
|
106
|
+
## print "abstract contract:"
|
107
|
+
## pp code
|
108
|
+
tree << [:abstract_contract, code]
|
109
|
+
when 'library'
|
110
|
+
code = s.scan_until( /(?=\{)/ )
|
111
|
+
code = _norm_whitespace( code )
|
112
|
+
## print "library:"
|
113
|
+
## pp code
|
114
|
+
tree << [:library, code]
|
115
|
+
when 'interface'
|
116
|
+
code = s.scan_until( /(?=\{)/ )
|
117
|
+
code = _norm_whitespace( code )
|
118
|
+
## print "interface:"
|
119
|
+
## pp code
|
120
|
+
tree << [:interface, code]
|
121
|
+
else
|
122
|
+
## slurp chunk ,that is, until newline or comment or tracked keyword
|
123
|
+
chunk = s.scan_until( END_OF_LINE_OR_COMMENT_OR_KEYWORD_OR_QUOTE ).rstrip
|
124
|
+
## puts "chunk: >#{chunk.inspect}<"
|
125
|
+
tree << chunk
|
126
|
+
end
|
127
|
+
end
|
128
|
+
break if s.eos?
|
129
|
+
end
|
130
|
+
|
131
|
+
tree
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
def outline
|
136
|
+
buf = String.new( '' )
|
137
|
+
tree = _quick_pass_one
|
138
|
+
|
139
|
+
tree.each do |node|
|
140
|
+
if node.is_a?( Array )
|
141
|
+
case node[0]
|
142
|
+
when :contract then buf << node[1] << "\n"
|
143
|
+
when :abstract_contract then buf << node[1] << "\n"
|
144
|
+
when :interface then buf << node[1] << "\n"
|
145
|
+
when :library then buf << node[1] << "\n"
|
146
|
+
else
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
buf
|
152
|
+
end
|
153
|
+
|
154
|
+
def pragmas
|
155
|
+
buf = String.new( '' )
|
156
|
+
tree = _quick_pass_one
|
157
|
+
|
158
|
+
tree.each do |node|
|
159
|
+
if node.is_a?( Array )
|
160
|
+
case node[0]
|
161
|
+
when :pragma then buf << node[1] << "\n"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
buf
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
end # class Parser
|
171
|
+
|
172
|
+
|
173
|
+
end # module Solidity
|
data/lib/solidity/version.rb
CHANGED
data/lib/solidity.rb
CHANGED
@@ -3,126 +3,9 @@ require 'cocos'
|
|
3
3
|
|
4
4
|
## our own code
|
5
5
|
require_relative 'solidity/version' # note: let version always go first
|
6
|
+
require_relative 'solidity/parser'
|
6
7
|
|
7
8
|
|
8
9
|
|
9
10
|
|
10
|
-
module Solidity
|
11
|
-
|
12
|
-
class Parser
|
13
|
-
def initialize( txt )
|
14
|
-
@txt = txt
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
SINGLE_COMMENT_RX = %r{^[ ]*//}
|
19
|
-
MULTI_COMMENT_BEGIN_RX = %r{^[ ]*/\*}
|
20
|
-
MULTI_COMMENT_END_RX = %r{\*/[ ]*$}
|
21
|
-
|
22
|
-
ID = '[a-zA-Z][a-zA-Z0-9]*'
|
23
|
-
|
24
|
-
PRAGMA_RX = %r{^[ ]*pragma}
|
25
|
-
LIBRARY_RX = %r{^[ ]*library[ ]+(?<id>#{ID})[ \{]}
|
26
|
-
ABSTRACT_CONTRACT_RX = %r{^[ ]*abstract[ ]+contract[ ]+(?<id>#{ID})[ \{]}
|
27
|
-
CONTRACT_RX = %r{^[ ]*contract[ ]+(?<id>#{ID})[ \{]}
|
28
|
-
INTERFACE_RX = %r{^[ ]*interface[ ]+(?<id>#{ID})[ \{]}
|
29
|
-
|
30
|
-
|
31
|
-
def _quick_pass_one
|
32
|
-
tree = []
|
33
|
-
node = nil
|
34
|
-
|
35
|
-
inside_comment = false
|
36
|
-
|
37
|
-
@txt.each_line do |line|
|
38
|
-
line = line.chomp ## remove trailing newline
|
39
|
-
## pp line
|
40
|
-
|
41
|
-
if inside_comment
|
42
|
-
node[1] << line
|
43
|
-
if MULTI_COMMENT_END_RX.match( line )
|
44
|
-
tree << node
|
45
|
-
inside_comment = false
|
46
|
-
end
|
47
|
-
else
|
48
|
-
if SINGLE_COMMENT_RX.match( line ) # end-of-line comments
|
49
|
-
line = line.strip ## remove leading & trailing spaces
|
50
|
-
## note: fold end-of-line comments into a block (if not separated by newline)
|
51
|
-
node = tree[-1]
|
52
|
-
if node.is_a?( Array ) &&
|
53
|
-
node[0] == :comment && node[1][0].start_with?( '//' )
|
54
|
-
node[1] << line
|
55
|
-
else
|
56
|
-
tree << [:comment, [line]]
|
57
|
-
end
|
58
|
-
elsif MULTI_COMMENT_BEGIN_RX.match( line )
|
59
|
-
inside_comment = true
|
60
|
-
node = [:comment, [line]]
|
61
|
-
elsif PRAGMA_RX.match( line )
|
62
|
-
line = line.strip
|
63
|
-
tree << [:pragma, line]
|
64
|
-
elsif LIBRARY_RX.match( line )
|
65
|
-
line = line.strip
|
66
|
-
tree << [:library, line]
|
67
|
-
elsif ABSTRACT_CONTRACT_RX.match( line )
|
68
|
-
line = line.strip
|
69
|
-
tree << [:abstract_contract, line]
|
70
|
-
elsif CONTRACT_RX.match( line )
|
71
|
-
line = line.strip
|
72
|
-
tree << [:contract, line]
|
73
|
-
elsif INTERFACE_RX.match( line )
|
74
|
-
line = line.strip
|
75
|
-
tree << [:interface, line]
|
76
|
-
else
|
77
|
-
tree << line
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end # each_line
|
81
|
-
|
82
|
-
tree
|
83
|
-
end
|
84
|
-
|
85
|
-
|
86
|
-
def outline
|
87
|
-
buf = String.new( '' )
|
88
|
-
tree = _quick_pass_one
|
89
|
-
|
90
|
-
tree.each do |node|
|
91
|
-
if node.is_a?( Array )
|
92
|
-
case node[0]
|
93
|
-
when :contract then buf << node[1] << "\n"
|
94
|
-
when :abstract_contract then buf << node[1] << "\n"
|
95
|
-
when :interface then buf << node[1] << "\n"
|
96
|
-
when :library then buf << node[1] << "\n"
|
97
|
-
else
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
buf
|
103
|
-
end
|
104
|
-
|
105
|
-
def pragmas
|
106
|
-
buf = String.new( '' )
|
107
|
-
tree = _quick_pass_one
|
108
|
-
|
109
|
-
tree.each do |node|
|
110
|
-
if node.is_a?( Array )
|
111
|
-
case node[0]
|
112
|
-
when :pragma then buf << node[1] << "\n"
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
buf
|
118
|
-
end
|
119
|
-
|
120
|
-
|
121
|
-
end # class Parser
|
122
|
-
|
123
|
-
|
124
|
-
end # module Solidity
|
125
|
-
|
126
|
-
|
127
|
-
|
128
11
|
puts Solidity.banner ## say hello
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solidity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
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-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cocos
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- README.md
|
73
73
|
- Rakefile
|
74
74
|
- lib/solidity.rb
|
75
|
+
- lib/solidity/parser.rb
|
75
76
|
- lib/solidity/version.rb
|
76
77
|
homepage: https://github.com/rubycocos/blockchain
|
77
78
|
licenses:
|