Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
geraldb committed Jan 29, 2023
1 parent 5a0a8a0 commit dca16a1
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Gems:
- [abidoc](abidoc) - application binary interface (abi) documentation generator for Ethereum & Co. (blockchain) contracts
- [abigen](abigen) - generate ready-to-use (blockchain) contract services / function calls for ethereum & co. via application binary interfaces (abis)
- [abibase](abibase) - command line tool / helper to manage application binary interfaces (abis)
- [solidity](solidity) - (fuzzy) parser for (crypto) contracts for ethereum & co.
- [ethlite](ethlite) - light-weight machinery to query / call ethereum (blockchain contract) services via json-rpc (incl. tuple support)
- [ethlite-contracts](ethlite-contracts) - pre-packaged ready-to-use "out-of-the-gem" (blockchain) contract services / function calls for ethereum & co
- [etherscan-lite](etherscan-lite) - light-weight machinery / helper for the Etherscan (blockchain) JSON HTTP API / web services (note: API key sign-up required)
Expand Down
35 changes: 35 additions & 0 deletions solidity/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
*.gem
*.rbc
/.config
/coverage/
/InstalledFiles
/pkg/
/spec/reports/
/test/tmp/
/test/version_tmp/
/tmp/

## Specific to RubyMotion:
.dat*
.repl_history
build/

## Documentation cache and generated files:
/.yardoc/
/_yardoc/
/doc/
/rdoc/

## Environment normalisation:
/.bundle/
/vendor/bundle
/lib/bundler/man/

# for a library or gem, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# Gemfile.lock
# .ruby-version
# .ruby-gemset

# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc
3 changes: 3 additions & 0 deletions solidity/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### 0.0.1 / 2019-04-12

* Everything is new. First release
6 changes: 6 additions & 0 deletions solidity/Manifest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CHANGELOG.md
Manifest.txt
README.md
Rakefile
lib/solidity.rb
lib/solidity/version.rb
9 changes: 9 additions & 0 deletions solidity/NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Notes About Solidity




## More

Awesome Solidity - <https://github.com/bkrem/awesome-solidity>

109 changes: 109 additions & 0 deletions solidity/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Solidity

solidity gem - (fuzzy) parser for (crypto) contracts for ethereum & co.


* home :: [github.com/rubycocos/blockchain](https://github.com/rubycocos/blockchain)
* bugs :: [github.com/rubycocos/blockchain/issues](https://github.com/rubycocos/blockchain/issues)
* gem :: [rubygems.org/gems/solidity](https://rubygems.org/gems/solidity)
* rdoc :: [rubydoc.info/gems/solidity](http://rubydoc.info/gems/solidity)





## Usage

Get / generate outline from source in the solidity (`.sol`) contract programming language:

```ruby
[
"0x34625ecaa75c0ea33733a05c584f4cf112c10b6b",
"0x0cfdb3ba1694c2bb2cfacb0339ad7b1ae5932b63",
"0x031920cc2d9f5c10b444fd44009cd64f829e7be2"
].each do |addr|

path = "awesome-contracts/address/#{addr}/contract.sol"
txt = read_text( path )

parser = Solidity::Parser.new( txt )

puts "---"
puts "outline:"
puts parser.outline

## bonus: dump the pragmas (required solidity compiler versions)
puts
puts "pragmas:"
puts parser.pragmas
```

Resulting in:

```
outline:
contract NounsDescriptor is INounsDescriptor, Ownable
abstract contract Ownable is Context
library Strings
interface INounsDescriptor
interface INounsSeeder
library NFTDescriptor
library MultiPartRLEToSVG
abstract contract Context
library Base64
```


```
outline:
contract Indelible is ERC721A, ReentrancyGuard, Ownable
library DynamicBuffer
library HelperLib
library SSTORE2
library Bytecode
abstract contract Ownable is Context
abstract contract ReentrancyGuard
library Address
library Base64
abstract contract Context
library MerkleProof
contract ERC721A is IERC721A
interface IERC721A
```


```
outline:
contract CryptoZunks is Ownable, ERC721Enumerable, ERC721Burnable, ReentrancyGuard
abstract contract Ownable is Context
abstract contract ReentrancyGuard
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata
abstract contract ERC721Burnable is Context, ERC721
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable
library Strings
library EnumerableMap
library console
abstract contract Context
interface IERC721 is IERC165
interface IERC721Receiver
interface IERC721Metadata is IERC721
library Address
abstract contract ERC165 is IERC165
interface IERC165
interface IERC721Enumerable is IERC721
library EnumerableSet
```




## License

The `solidity` scripts are dedicated to the public domain.
Use it as you please with no restrictions whatsoever.


## Questions? Comments?

Post them on the [D.I.Y. Punk (Pixel) Art reddit](https://old.reddit.com/r/DIYPunkArt). Thanks.

30 changes: 30 additions & 0 deletions solidity/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'hoe'
require './lib/solidity/version.rb'

Hoe.spec 'solidity' do

self.version = Solidity::VERSION

self.summary = "solidity - (fuzzy) parser for (crypto) contracts for ethereum & co."
self.description = summary

self.urls = { home: 'https://github.com/rubycocos/blockchain' }

self.author = 'Gerald Bauer'
self.email = '[email protected]'

# switch extension to .markdown for gihub formatting
self.readme_file = 'README.md'
self.history_file = 'CHANGELOG.md'

self.extra_deps = [
['cocos'],
]

self.licenses = ['Public Domain']

self.spec_extras = {
required_ruby_version: '>= 2.2.2'
}

end
128 changes: 128 additions & 0 deletions solidity/lib/solidity.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
require 'cocos'


## our own code
require_relative 'solidity/version' # note: let version always go first




module Solidity

class Parser
def initialize( txt )
@txt = txt
end


SINGLE_COMMENT_RX = %r{^[ ]*//}
MULTI_COMMENT_BEGIN_RX = %r{^[ ]*/\*}
MULTI_COMMENT_END_RX = %r{\*/[ ]*$}

ID = '[a-zA-Z][a-zA-Z0-9]*'

PRAGMA_RX = %r{^[ ]*pragma}
LIBRARY_RX = %r{^[ ]*library[ ]+(?<id>#{ID})[ \{]}
ABSTRACT_CONTRACT_RX = %r{^[ ]*abstract[ ]+contract[ ]+(?<id>#{ID})[ \{]}
CONTRACT_RX = %r{^[ ]*contract[ ]+(?<id>#{ID})[ \{]}
INTERFACE_RX = %r{^[ ]*interface[ ]+(?<id>#{ID})[ \{]}


def _quick_pass_one
tree = []
node = nil

inside_comment = false

@txt.each_line do |line|
line = line.chomp ## remove trailing newline
## pp line

if inside_comment
node[1] << line
if MULTI_COMMENT_END_RX.match( line )
tree << node
inside_comment = false
end
else
if SINGLE_COMMENT_RX.match( line ) # end-of-line comments
line = line.strip ## remove leading & trailing spaces
## note: fold end-of-line comments into a block (if not separated by newline)
node = tree[-1]
if node.is_a?( Array ) &&
node[0] == :comment && node[1][0].start_with?( '//' )
node[1] << line
else
tree << [:comment, [line]]
end
elsif MULTI_COMMENT_BEGIN_RX.match( line )
inside_comment = true
node = [:comment, [line]]
elsif PRAGMA_RX.match( line )
line = line.strip
tree << [:pragma, line]
elsif LIBRARY_RX.match( line )
line = line.strip
tree << [:library, line]
elsif ABSTRACT_CONTRACT_RX.match( line )
line = line.strip
tree << [:abstract_contract, line]
elsif CONTRACT_RX.match( line )
line = line.strip
tree << [:contract, line]
elsif INTERFACE_RX.match( line )
line = line.strip
tree << [:interface, line]
else
tree << line
end
end
end # each_line

tree
end


def outline
buf = String.new( '' )
tree = _quick_pass_one

tree.each do |node|
if node.is_a?( Array )
case node[0]
when :contract then buf << node[1] << "\n"
when :abstract_contract then buf << node[1] << "\n"
when :interface then buf << node[1] << "\n"
when :library then buf << node[1] << "\n"
else
end
end
end

buf
end

def pragmas
buf = String.new( '' )
tree = _quick_pass_one

tree.each do |node|
if node.is_a?( Array )
case node[0]
when :pragma then buf << node[1] << "\n"
end
end
end

buf
end


end # class Parser


end # module Solidity



puts Solidity.banner ## say hello
21 changes: 21 additions & 0 deletions solidity/lib/solidity/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

module Solidity

MAJOR = 0
MINOR = 1
PATCH = 1
VERSION = [MAJOR,MINOR,PATCH].join('.')

def self.version
VERSION
end

def self.banner
"solidity/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in (#{root})"
end

def self.root
File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
end

end # module Solidity
28 changes: 28 additions & 0 deletions solidity/sandbox/test_outline.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
###
# to run use
# ruby -I ./lib sandbox/test_outline.rb

require 'solidity'


## addr = "0x0cfdb3ba1694c2bb2cfacb0339ad7b1ae5932b63"
addr = "0x34625ecaa75c0ea33733a05c584f4cf112c10b6b"
## addr = "0x031920cc2d9f5c10b444fd44009cd64f829e7be2"

path = "../../awesome-contracts/address/#{addr}/contract.sol"
txt = read_text( path )


parser = Solidity::Parser.new( txt )
pp parser._quick_pass_one

puts "---"
puts "outline:"
puts parser.outline

puts
puts "pragmas:"
puts parser.pragmas


puts "bye"

0 comments on commit dca16a1

Please sign in to comment.