Class: Eth::Contract
- Inherits:
-
Object
- Object
- Eth::Contract
- Defined in:
- lib/eth/contract.rb
Overview
Provides classes to access smart contracts
Defined Under Namespace
Classes: Error, Event, Function, FunctionInput, FunctionOutput, Initializer
Instance Attribute Summary collapse
-
#abi ⇒ Object
Returns the value of attribute abi.
-
#address ⇒ Object
Returns the value of attribute address.
-
#bin ⇒ Object
Returns the value of attribute bin.
-
#class_object ⇒ Object
Returns the value of attribute class_object.
-
#constructor_inputs ⇒ Object
Returns the value of attribute constructor_inputs.
-
#errors ⇒ Object
Returns the value of attribute errors.
-
#events ⇒ Object
Returns the value of attribute events.
-
#functions ⇒ Object
Returns the value of attribute functions.
-
#gas_limit ⇒ Object
Returns the value of attribute gas_limit.
-
#gas_price ⇒ Object
Returns the value of attribute gas_price.
-
#key ⇒ Object
Returns the value of attribute key.
-
#max_fee_per_gas ⇒ Object
Returns the value of attribute max_fee_per_gas.
-
#max_priority_fee_per_gas ⇒ Object
Returns the value of attribute max_priority_fee_per_gas.
-
#name ⇒ Object
Returns the value of attribute name.
-
#nonce ⇒ Object
Returns the value of attribute nonce.
Class Method Summary collapse
-
.from_abi(abi:, address:, name:) ⇒ Eth::Contract::Object
Creates a contract wrapper from ABI and address.
-
.from_bin(bin:, abi:, name:) ⇒ Eth::Contract::Object
Creates a contract wrapper from binary and ABI.
-
.from_file(file:, contract_index: 0) ⇒ Eth::Contract::Object
Creates a contract wrapper from a Solidity file.
Instance Method Summary collapse
-
#build ⇒ Object
Create meta classes for smart contracts.
-
#decode_error(rpc_error) ⇒ String
Decodes a custom error returned by an RPC error using the contract ABI.
-
#error(name, args: nil) ⇒ Eth::Contract::Error
Finds an error by name.
-
#function(name, args: nil) ⇒ Eth::Contract::Function
Finds a function by name.
-
#initialize(name, bin, abi) ⇒ Contract
constructor
Constructor of the Contract class.
Constructor Details
#initialize(name, bin, abi) ⇒ Contract
Constructor of the Eth::Contract class.
Note, do not use this directly. Use from_abi, from_bin, or from_file!
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/eth/contract.rb', line 38 def initialize(name, bin, abi) # The contract name will be the class name and needs title casing. _name = name.dup _name[0] = name[0].upcase @name = _name @bin = bin @abi = abi @constructor_inputs, @functions, @events, @errors = parse_abi(abi) end |
Instance Attribute Details
#abi ⇒ Object
Returns the value of attribute abi.
27 28 29 |
# File 'lib/eth/contract.rb', line 27 def abi @abi end |
#address ⇒ Object
Returns the value of attribute address.
24 25 26 |
# File 'lib/eth/contract.rb', line 24 def address @address end |
#bin ⇒ Object
Returns the value of attribute bin.
27 28 29 |
# File 'lib/eth/contract.rb', line 27 def bin @bin end |
#class_object ⇒ Object
Returns the value of attribute class_object.
27 28 29 |
# File 'lib/eth/contract.rb', line 27 def class_object @class_object end |
#constructor_inputs ⇒ Object
Returns the value of attribute constructor_inputs.
28 29 30 |
# File 'lib/eth/contract.rb', line 28 def constructor_inputs @constructor_inputs end |
#errors ⇒ Object
Returns the value of attribute errors.
28 29 30 |
# File 'lib/eth/contract.rb', line 28 def errors @errors end |
#events ⇒ Object
Returns the value of attribute events.
28 29 30 |
# File 'lib/eth/contract.rb', line 28 def events @events end |
#functions ⇒ Object
Returns the value of attribute functions.
28 29 30 |
# File 'lib/eth/contract.rb', line 28 def functions @functions end |
#gas_limit ⇒ Object
Returns the value of attribute gas_limit.
26 27 28 |
# File 'lib/eth/contract.rb', line 26 def gas_limit @gas_limit end |
#gas_price ⇒ Object
Returns the value of attribute gas_price.
26 27 28 |
# File 'lib/eth/contract.rb', line 26 def gas_price @gas_price end |
#key ⇒ Object
Returns the value of attribute key.
25 26 27 |
# File 'lib/eth/contract.rb', line 25 def key @key end |
#max_fee_per_gas ⇒ Object
Returns the value of attribute max_fee_per_gas.
26 27 28 |
# File 'lib/eth/contract.rb', line 26 def max_fee_per_gas @max_fee_per_gas end |
#max_priority_fee_per_gas ⇒ Object
Returns the value of attribute max_priority_fee_per_gas.
26 27 28 |
# File 'lib/eth/contract.rb', line 26 def max_priority_fee_per_gas @max_priority_fee_per_gas end |
#name ⇒ Object
Returns the value of attribute name.
27 28 29 |
# File 'lib/eth/contract.rb', line 27 def name @name end |
#nonce ⇒ Object
Returns the value of attribute nonce.
26 27 28 |
# File 'lib/eth/contract.rb', line 26 def nonce @nonce end |
Class Method Details
.from_abi(abi:, address:, name:) ⇒ Eth::Contract::Object
Creates a contract wrapper from ABI and address.
71 72 73 74 75 76 77 78 |
# File 'lib/eth/contract.rb', line 71 def self.from_abi(abi:, address:, name:) abi = abi.is_a?(Array) ? abi : JSON.parse(abi) contract = Eth::Contract.new(name, nil, abi) contract.build contract = contract.class_object.new contract.address = address contract end |
.from_bin(bin:, abi:, name:) ⇒ Eth::Contract::Object
Creates a contract wrapper from binary and ABI.
88 89 90 91 92 93 |
# File 'lib/eth/contract.rb', line 88 def self.from_bin(bin:, abi:, name:) abi = abi.is_a?(Array) ? abi : JSON.parse(abi) contract = Eth::Contract.new(name, bin, abi) contract.build contract.class_object.new end |
.from_file(file:, contract_index: 0) ⇒ Eth::Contract::Object
Creates a contract wrapper from a Solidity file.
56 57 58 59 60 61 |
# File 'lib/eth/contract.rb', line 56 def self.from_file(file:, contract_index: 0) raise ArgumentError, "Cannot find the contract at #{file.to_s}!" if !File.exist?(file.to_s) contracts = Eth::Contract::Initializer.new(file).build_all raise ArgumentError, "No contracts compiled." if contracts.empty? contracts[contract_index].class_object.new end |
Instance Method Details
#build ⇒ Object
Create meta classes for smart contracts.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/eth/contract.rb', line 156 def build class_name = @name parent = self class_methods = Class.new do extend Forwardable def_delegators :parent, :key, :key= def_delegators :parent, :name, :abi, :bin def_delegators :parent, :gas_limit, :gas_price, :gas_limit=, :gas_price=, :nonce, :nonce= def_delegators :parent, :max_fee_per_gas, :max_fee_per_gas=, :max_priority_fee_per_gas, :max_priority_fee_per_gas= def_delegators :parent, :events, :errors def_delegators :parent, :address, :address= def_delegator :parent, :functions def_delegator :parent, :function def_delegator :parent, :error def_delegator :parent, :decode_error def_delegator :parent, :constructor_inputs define_method :parent do parent end end Eth::Contract.send(:remove_const, class_name) if Eth::Contract.const_defined?(class_name, false) Eth::Contract.const_set(class_name, class_methods) @class_object = class_methods end |
#decode_error(rpc_error) ⇒ String
Decodes a custom error returned by an RPC error using the contract ABI.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/eth/contract.rb', line 137 def decode_error(rpc_error) data = rpc_error.data return rpc_error. if data.nil? || errors.nil? signature = data[0, 10] if (err = errors.find { |e| e.signature == signature }) values = err.decode(data) args = values&.map { |v| v.is_a?(String) ? v : v.inspect }&.join(",") args ||= "" "execution reverted: #{err.name}(#{args})" elsif signature == "0x08c379a0" reason = Abi.decode(["string"], "0x" + data[10..])&.first "execution reverted: #{reason}" else rpc_error. end end |
#error(name, args: nil) ⇒ Eth::Contract::Error
Finds an error by name.
127 128 129 130 131 |
# File 'lib/eth/contract.rb', line 127 def error(name, args: nil) errors.find do |e| e.name == name && (args.nil? || args == e.inputs.size) end || raise(ArgumentError, "this error does not exist!") end |
#function(name, args: nil) ⇒ Eth::Contract::Function
Finds a function by name.
115 116 117 118 119 |
# File 'lib/eth/contract.rb', line 115 def function(name, args: nil) functions.find do |f| f.name == name && (args.nil? || args == f.inputs.size) end || raise(ArgumentError, "this function does not exist!") end |