Class: AbiProxy
- Inherits:
-
Object
- Object
- AbiProxy
- Defined in:
- lib/rubysol/abi_proxy.rb
Instance Attribute Summary collapse
-
#contract_class ⇒ Object
todo: make data private!!! make read access available via #each !!!.
Class Method Summary collapse
-
.contract_classes ⇒ Object
keep a list of generated classes (only needed/possible to generatae once).
Instance Method Summary collapse
- #_contract_classes ⇒ Object
- #_generate_functions(contract_class) ⇒ Object
- #_merge_state_variables(parents) ⇒ Object
- #generate_functions ⇒ Object
-
#generated? ⇒ Boolean
generated? - use flag to keep track of code generation (only one time needed/required).
-
#initialize(contract_class) ⇒ AbiProxy
constructor
A new instance of AbiProxy.
- #public_abi ⇒ Object (also: #public_api)
-
#public_abi_as_json ⇒ Object
rename to to_abi_json or export_abi_json or solidity_abi_json or ??.
- #public_abi_to_json ⇒ Object
Constructor Details
#initialize(contract_class) ⇒ AbiProxy
Returns a new instance of AbiProxy.
9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/rubysol/abi_proxy.rb', line 9 def initialize(contract_class) @contract_class = contract_class @generated = false parents = contract_class.linearized_parents if parents.empty? ## do nothing else _merge_state_variables( parents) end end |
Instance Attribute Details
#contract_class ⇒ Object
todo: make data private!!!
make read access available via #each !!!
7 8 9 |
# File 'lib/rubysol/abi_proxy.rb', line 7 def contract_class @contract_class end |
Class Method Details
.contract_classes ⇒ Object
keep a list of generated classes (only needed/possible to generatae once)
23 |
# File 'lib/rubysol/abi_proxy.rb', line 23 def self.contract_classes() @classes ||= []; end |
Instance Method Details
#_contract_classes ⇒ Object
24 |
# File 'lib/rubysol/abi_proxy.rb', line 24 def _contract_classes() self.class.contract_classes; end |
#_generate_functions(contract_class) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/rubysol/abi_proxy.rb', line 43 def _generate_functions( contract_class ) ## start with simple (no parents) for now sigs = contract_class.sigs puts "#{sigs.size} function signatures in #{contract_class.name}:" pp sigs ## note: only generate once for now!!!! ## maybe check later if new sigs?? possible? why? why not? if _contract_classes.include?( contract_class ) puts " already generated!" else ## generate global function (e.g. ERC20() or such) Generator.global_function( contract_class ) # sigs.each do |name, definition| # Generator.typed_function( contract_class, name, # inputs: definition[:inputs] ) # end _contract_classes << contract_class end end |
#_merge_state_variables(parents) ⇒ Object
74 75 76 77 78 79 80 81 82 |
# File 'lib/rubysol/abi_proxy.rb', line 74 def _merge_state_variables( parents ) puts "[debug] AbiProxy#merge_parent_state_variables - #{contract_class}" parent_state_variables = parents.map(&:state_variable_definitions).reverse vars = parent_state_variables.reduce( {} ) { |mem,h| mem.merge(h) } .merge( contract_class.state_variable_definitions) puts "[debug] merged state_variables:" pp vars contract_class.state_variable_definitions = vars end |
#generate_functions ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/rubysol/abi_proxy.rb', line 29 def generate_functions @generated = true puts "==> generate (typed) functions for #{@contract_class.name}" parents = @contract_class.linearized_parents ## revesee order - why? why not? parents.each do |parent| _generate_functions( parent ) end _generate_functions( @contract_class ) end |
#generated? ⇒ Boolean
generated? - use flag to keep track of code generation (only one time needed/required)
28 |
# File 'lib/rubysol/abi_proxy.rb', line 28 def generated?() @generated; end |
#public_abi ⇒ Object Also known as: public_api
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/rubysol/abi_proxy.rb', line 86 def public_abi ### note: calculate for now on-the-fly - why? why not? ## cache results - why? why not? contracts = [@contract_class] + @contract_class.linearized_parents ## note: use reverse order - ## most concreate comes last (for override) contracts = contracts.reverse ## todo/fix: add (contract) klass for source to data??? - why? why not? data = {} contracts.each do |klass| klass.sigs.each do |name, definition| if definition[:options].include?( :public ) ## check for override ## and issue info for now if data.has_key?( name ) ## Solidity lets developers change how a function in the parent contract is implemented ## in the derived class. This is known as function overriding. ## The function in the parent contract needs to be declared with ## the keyword virtual to indicate that it can be overridden ## in the deriving contract. ## ## todo: check for virtual keyword - why? why not? if name == :constructor puts " overriding constructor in #{klass.name}" else puts " overriding function #{name} in #{klass.name}" end end data[name] = definition else puts " skip non-public sig - #{name} #{definition.inspect}" end end end data end |
#public_abi_as_json ⇒ Object
rename to to_abi_json or export_abi_json or solidity_abi_json or ??
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/rubysol/abi_proxy.rb', line 130 def public_abi_as_json ## ## todo/fix: add events too!!! ## todo/fix: add input parameter names too!!!! # json format: # Type - defines the nature of the function (receive, fallback, constructor) # Name - defines the name of the function # Inputs - array of objects with name, type, components # Outputs - array of objects similar to inputs # stateMutability - defines the mutability of the function (pure, view, non-payable or payable) # # "type": "constructor", # "inputs": [ # { "type": "string", "name": "symbol" }, # { "type": "string", "name": "name" } # ] # # "type": "function", # "name": "balanceOf", # "stateMutability": "view", # "inputs": [ # { "type": "address", "name": "owner"} # ], # "outputs": [ # { "type": "uint256"} # ] data = [] public_abi.each do |name, definition| inputs = definition[:inputs].map do |input| ## todo: use a _arg1, _arg2, ## count or such - why? { 'type' => input.to_s, 'name' => '_' } end state_mutability = 'nonpayable' ## default is nonpayable (double check) state_mutability = 'view' if definition[:options].include?( :view ) if name == :constructor data << { 'type' => 'constructor', 'stateMutability' => state_mutability, 'inputs' => inputs } else ## check if outputs is a single entry or array or nil or hash? outputs = definition[:outputs].is_a?( Array ) ? definition[:outputs] : [definition[:outputs]] outputs = outputs.map do |output| ## todo: use a _arg1, _arg2, ## count or such - why? { 'type' => output.to_s, 'name' => '_' } end data << { 'type' => 'function', 'name' => name.to_s, 'stateMutability' => state_mutability, 'inputs' => inputs, 'outputs' => outputs, } end end data end |
#public_abi_to_json ⇒ Object
203 204 205 |
# File 'lib/rubysol/abi_proxy.rb', line 203 def public_abi_to_json JSON.pretty_generate( public_abi_as_json ) end |