facetq 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62514c7ce665930ee9a2bfed08a4b4cd6b03a40ad5435bb27f36a28855a68e49
4
- data.tar.gz: 48c9bd928542012c9da8369b5ed3542092fb905ce2069d4e4dab49e4ccd09af2
3
+ metadata.gz: 6b77cfad6fa050f005e3f8b15524d6b8cfc17ed626d3cd246e76dc8d5d4fed28
4
+ data.tar.gz: 66c7cd8926bb21f8fc6c3f14396a66247215063c1d9a0792b5f3e900e076e698
5
5
  SHA512:
6
- metadata.gz: aace02cbb67889f09178f259e86f1d0610941ba033d64df377cfae01f176dbf5117b002799448cfd7d34945ce9ed3d0a5e38acb61383ce9a86bb9f252aaf5beb
7
- data.tar.gz: 1a342b27a236f3f1adddf1c4710622c212086ae1002333efbf38e4d5d985e9201fbd1873f01ae3096f8aca8ec05c9d889f5007cef14c005e8dc26ff8e660a7ed
6
+ metadata.gz: 7b2ea766d1877ce7de26e09f04f9e11d0fde022b68f79ece6bb41be87e29aa007154e36bd3ffa9df22b19f3757240b54e492791d5fbe3d954e3731679f3677c4
7
+ data.tar.gz: 2d19007f0c709e9368a5cd78dce21e5a5f43af3c1bd599ae095e8a961bcfbab3c8b7636b152624b441457ce77519c182fc8b813a05bad5a4e0ef660723102f07
data/CHANGELOG.md CHANGED
@@ -1,3 +1,4 @@
1
+ ### 0.1.0
1
2
  ### 0.0.1 / 2023-12-07
2
3
 
3
4
  * Everything is new. First release
data/Manifest.txt CHANGED
@@ -3,6 +3,13 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/facetq.rb
6
- lib/facetq/eth_block.rb
7
- lib/facetq/ethscription.rb
8
- lib/facetq/transaction_receipt.rb
6
+ lib/facetq/json_sorter.rb
7
+ lib/facetq/models/contract.rb
8
+ lib/facetq/models/contract_artifact.rb
9
+ lib/facetq/models/contract_call.rb
10
+ lib/facetq/models/contract_state.rb
11
+ lib/facetq/models/contract_transaction.rb
12
+ lib/facetq/models/eth_block.rb
13
+ lib/facetq/models/ethscription.rb
14
+ lib/facetq/models/system_config_version.rb
15
+ lib/facetq/models/transaction_receipt.rb
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Facet Q - Facet Models For Easy SQL Database Queries
1
+ # Facet Q - Facet Models For SQL Database Queries
2
2
 
3
- facetq - "stand-alone" facet (activerecord) models for easy sql database queries and more
3
+ facetq - "stand-alone" facet (activerecord) models for easy (re)use for sql database queries and more
4
4
 
5
5
  * home :: [github.com/0xCompute/rubidity](https://github.com/0xCompute/rubidity)
6
6
  * bugs :: [github.com/0xCompute/rubidity/issues](https://github.com/0xCompute/rubidity/issues)
@@ -16,10 +16,10 @@ require 'facetq'
16
16
 
17
17
  ## step 1: connect to database
18
18
  config = {
19
- adapter: 'postgresql'
20
- encoding: 'unicode'
21
- database: 'ethscriptions_vm_development'
22
- username: '<your username here>'
19
+ adapter: 'postgresql',
20
+ encoding: 'unicode',
21
+ database: 'ethscriptions_vm_development',
22
+ username: '<your username here>',
23
23
  password: '<your password here>'
24
24
  }
25
25
  ActiveRecord::Base.establish_connection( config )
@@ -28,9 +28,22 @@ ActiveRecord::Base.establish_connection( config )
28
28
  puts " #{EthBlock.count} block(s)"
29
29
  puts " #{Ethscription.count} ethscription(s)"
30
30
  puts " #{TransactionReceipt.count} receipt(s)"
31
- #=> 19998 block(s)
32
- # 1 ethscription(s)
33
- # 0 receipt(s)
31
+ puts " #{ContractArtifact.count} contract artifact(s)"
32
+ puts " #{Contract.count} contract(s)"
33
+ puts " #{ContractTransaction.count} contract transaction(s)"
34
+ puts " #{ContractCall.count} contract call(s)"
35
+ puts " #{ContractState.count} countract state(s)"
36
+ puts " #{SystemConfigVersion.count} system config version(s)"
37
+ #=> 107353 block(s)
38
+ # 294056 ethscription(s)
39
+ # 33798 receipt(s)
40
+ # 8 contract artifact(s)
41
+ # 38 contract(s)
42
+ # 33798 contract transaction(s)
43
+ # 34295 contract call(s)
44
+ # 29541 countract state(s)
45
+ # 5 system config version(s)
46
+
34
47
 
35
48
  ## lets try some more queries
36
49
  data = EthBlock.order(:block_number).limit(1)
@@ -58,6 +71,8 @@ pp data.as_json
58
71
  # "processing_state"=>"complete",
59
72
  # "transaction_count"=>0}]
60
73
 
74
+
75
+ # and so forth
61
76
  ```
62
77
 
63
78
  That's it for now.
data/Rakefile CHANGED
@@ -3,9 +3,9 @@ require 'hoe'
3
3
 
4
4
 
5
5
  Hoe.spec 'facetq' do
6
- self.version = '0.0.1'
6
+ self.version = '0.1.0'
7
7
 
8
- self.summary = 'facetq - "stand-alone" facet (activerecord) models for easy sql database queries and more'
8
+ self.summary = 'facetq - "stand-alone" facet (activerecord) models for easy (re)use for sql database queries and more'
9
9
  self.description = summary
10
10
 
11
11
  self.urls = { home: 'https://github.com/0xCompute/rubidity' }
@@ -0,0 +1,10 @@
1
+
2
+ module JsonSorter
3
+ def self.sort_hash(hash)
4
+ sorted = hash.sort_by { |k, _| [k.length, k] }
5
+
6
+ sorted.each_with_object({}) do |(key, value), result|
7
+ result[key] = value.is_a?(Hash) ? sort_hash(value) : value
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,81 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: contracts
4
+ #
5
+ # id :bigint not null, primary key
6
+ # transaction_hash :string not null
7
+ # block_number :bigint not null
8
+ # transaction_index :bigint not null
9
+ # current_type :string
10
+ # current_init_code_hash :string
11
+ # current_state :jsonb not null
12
+ # address :string not null
13
+ # deployed_successfully :boolean not null
14
+ # created_at :datetime not null
15
+ # updated_at :datetime not null
16
+ #
17
+ # Indexes
18
+ #
19
+ # idx_on_address_deployed_successfully (address) UNIQUE WHERE (deployed_successfully = true)
20
+ # index_contracts_on_address (address) UNIQUE
21
+ # index_contracts_on_current_init_code_hash (current_init_code_hash)
22
+ # index_contracts_on_current_state (current_state) USING gin
23
+ # index_contracts_on_current_type (current_type)
24
+ # index_contracts_on_deployed_successfully (deployed_successfully)
25
+ # index_contracts_on_deployed_successfully_and_address (deployed_successfully,address) UNIQUE
26
+ # index_contracts_on_transaction_hash (transaction_hash)
27
+ #
28
+ # Foreign Keys
29
+ #
30
+ # fk_rails_... (block_number => eth_blocks.block_number) ON DELETE => cascade
31
+ # fk_rails_... (transaction_hash => ethscriptions.transaction_hash) ON DELETE => cascade
32
+ #
33
+ class Contract < ActiveRecord::Base
34
+
35
+ has_many :states, primary_key: 'address', foreign_key: 'contract_address', class_name: "ContractState"
36
+ belongs_to :contract_transaction, foreign_key: :transaction_hash, primary_key: :transaction_hash, optional: true
37
+
38
+ belongs_to :ethscription, primary_key: 'transaction_hash', foreign_key: 'transaction_hash', optional: true
39
+
40
+ has_many :contract_calls, foreign_key: :effective_contract_address, primary_key: :address
41
+ has_one :transaction_receipt, through: :contract_transaction
42
+
43
+
44
+
45
+ after_initialize :set_normalized_initial_state
46
+
47
+ def set_normalized_initial_state
48
+ @normalized_initial_state = JsonSorter.sort_hash(current_state)
49
+ end
50
+
51
+ def normalized_state_changed?
52
+ @normalized_initial_state != JsonSorter.sort_hash(current_state)
53
+ end
54
+
55
+
56
+ def as_json(options = {})
57
+ super(
58
+ options.merge(
59
+ only: [
60
+ :address,
61
+ :transaction_hash,
62
+ :current_init_code_hash,
63
+ :current_type
64
+ ]
65
+ )
66
+ ).tap do |json|
67
+
68
+ if association(:transaction_receipt).loaded?
69
+ json['deployment_transaction'] = transaction_receipt
70
+ end
71
+
72
+ json['current_state'] = if options[:include_current_state]
73
+ current_state
74
+ else
75
+ {}
76
+ end
77
+
78
+ json['current_state']['contract_type'] = current_type
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,54 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: contract_artifacts
4
+ #
5
+ # id :bigint not null, primary key
6
+ # transaction_hash :string not null
7
+ # internal_transaction_index :bigint not null
8
+ # block_number :bigint not null
9
+ # transaction_index :bigint not null
10
+ # name :string not null
11
+ # source_code :text not null
12
+ # init_code_hash :string not null
13
+ # references :jsonb not null
14
+ # pragma_language :string not null
15
+ # pragma_version :string not null
16
+ # created_at :datetime not null
17
+ # updated_at :datetime not null
18
+ #
19
+ # Indexes
20
+ #
21
+ # idx_on_block_number_transaction_index_internal_tran_570359f80e (block_number,transaction_index,internal_transaction_index) UNIQUE
22
+ # idx_on_transaction_hash_internal_transaction_index_c95378cab3 (transaction_hash,internal_transaction_index) UNIQUE
23
+ # index_contract_artifacts_on_init_code_hash (init_code_hash) UNIQUE
24
+ # index_contract_artifacts_on_name (name)
25
+ #
26
+ # Foreign Keys
27
+ #
28
+ # fk_rails_... (block_number => eth_blocks.block_number) ON DELETE => cascade
29
+ # fk_rails_... (transaction_hash => ethscriptions.transaction_hash) ON DELETE => cascade
30
+ #
31
+ class ContractArtifact < ActiveRecord::Base # ApplicationRecord
32
+
33
+ belongs_to :contract_transaction, foreign_key: :transaction_hash, primary_key: :transaction_hash, optional: true
34
+
35
+ scope :newest_first, -> {
36
+ order(
37
+ block_number: :desc,
38
+ transaction_index: :desc,
39
+ internal_transaction_index: :desc
40
+ )
41
+ }
42
+
43
+ def as_json(options = {})
44
+ super(
45
+ options.merge(
46
+ only: [
47
+ :name,
48
+ :source_code,
49
+ :init_code_hash
50
+ ]
51
+ )
52
+ )
53
+ end
54
+ end
@@ -0,0 +1,170 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: contract_calls
4
+ #
5
+ # id :bigint not null, primary key
6
+ # transaction_hash :string not null
7
+ # internal_transaction_index :bigint not null
8
+ # from_address :string not null
9
+ # to_contract_address :string
10
+ # created_contract_address :string
11
+ # effective_contract_address :string
12
+ # function :string
13
+ # args :jsonb not null
14
+ # call_type :string not null
15
+ # return_value :jsonb
16
+ # logs :jsonb not null
17
+ # error :jsonb
18
+ # status :string not null
19
+ # block_number :bigint not null
20
+ # block_timestamp :bigint not null
21
+ # block_blockhash :string not null
22
+ # transaction_index :bigint not null
23
+ # start_time :datetime not null
24
+ # end_time :datetime not null
25
+ # runtime_ms :integer not null
26
+ # created_at :datetime not null
27
+ # updated_at :datetime not null
28
+ #
29
+ # Indexes
30
+ #
31
+ # idx_on_block_number_txi_internal_txi (block_number,transaction_index,internal_transaction_index) UNIQUE
32
+ # idx_on_tx_hash_internal_txi (transaction_hash,internal_transaction_index) UNIQUE
33
+ # index_contract_calls_on_call_type (call_type)
34
+ # index_contract_calls_on_created_contract_address (created_contract_address) UNIQUE
35
+ # index_contract_calls_on_effective_contract_address (effective_contract_address)
36
+ # index_contract_calls_on_from_address (from_address)
37
+ # index_contract_calls_on_internal_transaction_index (internal_transaction_index)
38
+ # index_contract_calls_on_status (status)
39
+ # index_contract_calls_on_to_contract_address (to_contract_address)
40
+ #
41
+ # Foreign Keys
42
+ #
43
+ # fk_rails_... (block_number => eth_blocks.block_number) ON DELETE => cascade
44
+ # fk_rails_... (transaction_hash => ethscriptions.transaction_hash) ON DELETE => cascade
45
+ #
46
+ class ContractCall < ActiveRecord::Base # ApplicationRecord
47
+
48
+
49
+ attr_accessor :to_contract, :salt, :pending_logs, :to_contract_init_code_hash, :to_contract_source_code
50
+
51
+ belongs_to :created_contract, class_name: 'Contract', primary_key: 'address', foreign_key: 'created_contract_address', optional: true
52
+ belongs_to :called_contract, class_name: 'Contract', primary_key: 'address', foreign_key: 'to_contract_address', optional: true
53
+ belongs_to :effective_contract, class_name: 'Contract', primary_key: 'address', foreign_key: 'effective_contract_address', optional: true
54
+
55
+ belongs_to :contract_transaction, foreign_key: :transaction_hash, primary_key: :transaction_hash, optional: true, inverse_of: :contract_calls
56
+
57
+ belongs_to :ethscription, primary_key: 'transaction_hash', foreign_key: 'transaction_hash', optional: true
58
+
59
+ scope :newest_first, -> { order(
60
+ block_number: :desc,
61
+ transaction_index: :desc,
62
+ internal_transaction_index: :desc
63
+ ) }
64
+
65
+
66
+
67
+
68
+ def contract_nonce
69
+ in_memory = contract_transaction.contract_calls.count do |call|
70
+ call.from_address == from_address &&
71
+ call.is_create? &&
72
+ call.success?
73
+ end
74
+
75
+ scope = ContractCall.where(
76
+ from_address: from_address,
77
+ call_type: :create,
78
+ status: :success
79
+ )
80
+
81
+ in_memory + scope.count
82
+ end
83
+
84
+ def eoa_nonce
85
+ scope = ContractCall.where(
86
+ from_address: from_address,
87
+ call_type: [:create, :call]
88
+ )
89
+
90
+ scope.count
91
+ end
92
+
93
+ def current_nonce
94
+ raise "Not possible" unless is_create?
95
+
96
+ contract_initiated? ? contract_nonce : eoa_nonce
97
+ end
98
+
99
+ def contract_initiated?
100
+ internal_transaction_index > 0
101
+ end
102
+
103
+
104
+ def to
105
+ to_contract_address
106
+ end
107
+
108
+ def from
109
+ from_address
110
+ end
111
+
112
+ def contract_address
113
+ created_contract_address
114
+ end
115
+
116
+ def to_or_contract_address
117
+ to || contract_address
118
+ end
119
+
120
+ def as_json(options = {})
121
+ super(
122
+ options.merge(
123
+ only: [
124
+ :transaction_hash,
125
+ :block_blockhash,
126
+ :block_timestamp,
127
+ :block_number,
128
+ :transaction_index,
129
+ :internal_transaction_index,
130
+ :function,
131
+ :args,
132
+ :call_type,
133
+ :return_value,
134
+ :logs,
135
+ :error,
136
+ :status,
137
+ :runtime_ms,
138
+ :effective_contract_address
139
+ ],
140
+ methods: [:to, :from, :contract_address, :to_or_contract_address]
141
+ )
142
+ )
143
+ end
144
+
145
+ def calculated_runtime_ms
146
+ (end_time - start_time) * 1000
147
+ end
148
+
149
+ def is_static_call?
150
+ call_type.to_s == "static_call"
151
+ end
152
+
153
+ def is_create?
154
+ call_type.to_s == "create"
155
+ end
156
+
157
+ def is_call?
158
+ call_type.to_s == "call"
159
+ end
160
+
161
+ def failure?
162
+ status.to_s == 'failure'
163
+ end
164
+
165
+ def success?
166
+ status.to_s == 'success'
167
+ end
168
+
169
+
170
+ end
@@ -0,0 +1,54 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: contract_states
4
+ #
5
+ # id :bigint not null, primary key
6
+ # transaction_hash :string not null
7
+ # type :string not null
8
+ # init_code_hash :string not null
9
+ # state :jsonb not null
10
+ # block_number :bigint not null
11
+ # transaction_index :bigint not null
12
+ # contract_address :string not null
13
+ # created_at :datetime not null
14
+ # updated_at :datetime not null
15
+ #
16
+ # Indexes
17
+ #
18
+ # index_contract_states_on_addr_block_number_tx_index (contract_address,block_number,transaction_index) UNIQUE
19
+ # index_contract_states_on_contract_address (contract_address)
20
+ # index_contract_states_on_contract_address_and_transaction_hash (contract_address,transaction_hash) UNIQUE
21
+ # index_contract_states_on_state (state) USING gin
22
+ # index_contract_states_on_transaction_hash (transaction_hash)
23
+ #
24
+ # Foreign Keys
25
+ #
26
+ # fk_rails_... (block_number => eth_blocks.block_number) ON DELETE => cascade
27
+ # fk_rails_... (contract_address => contracts.address) ON DELETE => cascade
28
+ # fk_rails_... (transaction_hash => ethscriptions.transaction_hash) ON DELETE => cascade
29
+ #
30
+ class ContractState < ActiveRecord::Base
31
+ self.inheritance_column = :_type_disabled
32
+
33
+ belongs_to :contract, foreign_key: :contract_address, primary_key: :address, optional: true
34
+ belongs_to :contract_transaction, foreign_key: :transaction_hash, primary_key: :transaction_hash, optional: true
35
+ belongs_to :ethscription,
36
+ primary_key: 'transaction_hash', foreign_key: 'transaction_hash',
37
+ optional: true
38
+
39
+ scope :newest_first, -> {
40
+ order(block_number: :desc, transaction_index: :desc)
41
+ }
42
+
43
+ def as_json(options = {})
44
+ super(
45
+ options.merge(
46
+ only: [
47
+ :transaction_hash,
48
+ :contract_address,
49
+ :state,
50
+ ]
51
+ )
52
+ )
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: contract_transactions
4
+ #
5
+ # id :bigint not null, primary key
6
+ # transaction_hash :string not null
7
+ # block_blockhash :string not null
8
+ # block_timestamp :bigint not null
9
+ # block_number :bigint not null
10
+ # transaction_index :bigint not null
11
+ # created_at :datetime not null
12
+ # updated_at :datetime not null
13
+ #
14
+ # Indexes
15
+ #
16
+ # index_contract_transactions_on_transaction_hash (transaction_hash) UNIQUE
17
+ # index_contract_txs_on_block_number_and_tx_index (block_number,transaction_index) UNIQUE
18
+ #
19
+ # Foreign Keys
20
+ #
21
+ # fk_rails_... (block_number => eth_blocks.block_number) ON DELETE => cascade
22
+ # fk_rails_... (transaction_hash => ethscriptions.transaction_hash) ON DELETE => cascade
23
+ #
24
+ class ContractTransaction < ActiveRecord::Base
25
+
26
+ belongs_to :ethscription, primary_key: :transaction_hash, foreign_key: :transaction_hash, optional: true
27
+ has_one :transaction_receipt, foreign_key: :transaction_hash, primary_key: :transaction_hash
28
+ has_many :contract_states, foreign_key: :transaction_hash, primary_key: :transaction_hash
29
+ has_many :contract_calls, foreign_key: :transaction_hash, primary_key: :transaction_hash, inverse_of: :contract_transaction
30
+ has_many :contracts, foreign_key: :transaction_hash, primary_key: :transaction_hash
31
+ has_many :contract_artifacts, foreign_key: :transaction_hash, primary_key: :transaction_hash
32
+
33
+ attr_accessor :tx_origin, :payload
34
+
35
+ def self.transaction_mimetype
36
+ "application/vnd.facet.tx+json"
37
+ end
38
+
39
+
40
+
41
+
42
+ def status
43
+ contract_calls.any?(&:failure?) ? :failure : :success
44
+ end
45
+ end
@@ -0,0 +1,64 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: eth_blocks
4
+ #
5
+ # id :bigint not null, primary key
6
+ # block_number :bigint not null
7
+ # timestamp :bigint not null
8
+ # blockhash :string not null
9
+ # parent_blockhash :string not null
10
+ # imported_at :datetime not null
11
+ # processing_state :string not null
12
+ # transaction_count :bigint
13
+ # runtime_ms :integer
14
+ # created_at :datetime not null
15
+ # updated_at :datetime not null
16
+ #
17
+ # Indexes
18
+ #
19
+ # index_eth_blocks_on_block_number (block_number) UNIQUE
20
+ # index_eth_blocks_on_block_number_completed (block_number) WHERE ((processing_state)::text = 'complete'::text)
21
+ # index_eth_blocks_on_block_number_pending (block_number) WHERE ((processing_state)::text = 'pending'::text)
22
+ # index_eth_blocks_on_blockhash (blockhash) UNIQUE
23
+ # index_eth_blocks_on_imported_at (imported_at)
24
+ # index_eth_blocks_on_imported_at_and_processing_state (imported_at,processing_state)
25
+ # index_eth_blocks_on_parent_blockhash (parent_blockhash) UNIQUE
26
+ # index_eth_blocks_on_processing_state (processing_state)
27
+ # index_eth_blocks_on_timestamp (timestamp)
28
+ #
29
+
30
+
31
+ class EthBlock < ActiveRecord::Base # ApplicationRecord
32
+
33
+ has_many :ethscriptions, foreign_key: :block_number, primary_key: :block_number
34
+ has_many :transaction_receipts, foreign_key: :block_number, primary_key: :block_number
35
+
36
+ scope :newest_first, -> { order(block_number: :desc) }
37
+ scope :oldest_first, -> { order(block_number: :asc) }
38
+
39
+ scope :processed, -> { where.not(processing_state: "pending") }
40
+
41
+ def self.max_processed_block_number
42
+ EthBlock.processed.maximum(:block_number).to_i
43
+ end
44
+
45
+
46
+
47
+ def as_json(options = {})
48
+ super(options.merge(
49
+ only: [
50
+ :block_number,
51
+ :timestamp,
52
+ :blockhash,
53
+ :parent_blockhash,
54
+ :imported_at,
55
+ :processing_state,
56
+ :transaction_count,
57
+ ]
58
+ )).tap do |json|
59
+ if association(:transaction_receipts).loaded?
60
+ json[:transaction_receipts] = transaction_receipts.map(&:as_json)
61
+ end
62
+ end.with_indifferent_access
63
+ end
64
+ end
@@ -0,0 +1,79 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: ethscriptions
4
+ #
5
+ # id :bigint not null, primary key
6
+ # transaction_hash :string not null
7
+ # block_number :bigint not null
8
+ # block_blockhash :string not null
9
+ # transaction_index :bigint not null
10
+ # creator :string not null
11
+ # initial_owner :string not null
12
+ # block_timestamp :bigint not null
13
+ # content_uri :text not null
14
+ # mimetype :string not null
15
+ # processed_at :datetime
16
+ # processing_state :string not null
17
+ # processing_error :string
18
+ # gas_price :bigint
19
+ # gas_used :bigint
20
+ # transaction_fee :bigint
21
+ # created_at :datetime not null
22
+ # updated_at :datetime not null
23
+ #
24
+ # Indexes
25
+ #
26
+ # index_ethscriptions_on_block_number_and_transaction_index (block_number,transaction_index) UNIQUE
27
+ # index_ethscriptions_on_processing_state (processing_state)
28
+ # index_ethscriptions_on_transaction_hash (transaction_hash) UNIQUE
29
+ #
30
+ # Foreign Keys
31
+ #
32
+ # fk_rails_... (block_number => eth_blocks.block_number) ON DELETE => cascade
33
+ #
34
+
35
+
36
+ class Ethscription < ActiveRecord::Base # ApplicationRecord
37
+
38
+ belongs_to :eth_block, foreign_key: :block_number, primary_key: :block_number, optional: true
39
+
40
+ has_many :contracts, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
41
+
42
+ has_one :transaction_receipt, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
43
+
44
+ has_one :contract_transaction, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
45
+ has_one :system_config_version, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
46
+ has_many :contract_states, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
47
+
48
+ before_validation :downcase_hex_fields
49
+
50
+ scope :newest_first, -> { order(block_number: :desc, transaction_index: :desc) }
51
+ scope :oldest_first, -> { order(block_number: :asc, transaction_index: :asc) }
52
+
53
+ scope :unprocessed, -> { where(processing_state: "pending") }
54
+
55
+ def content
56
+ content_uri[/.*?,(.*)/, 1]
57
+ end
58
+
59
+ def parsed_content
60
+ JSON.parse(content)
61
+ end
62
+
63
+ def processed?
64
+ processing_state != "pending"
65
+ end
66
+
67
+ def self.required_initial_owner
68
+ "0x00000000000000000000000000000000000face7"
69
+ end
70
+
71
+
72
+ private
73
+
74
+ def downcase_hex_fields
75
+ self.transaction_hash = transaction_hash.downcase
76
+ self.creator = creator.downcase
77
+ self.initial_owner = initial_owner.downcase
78
+ end
79
+ end
@@ -0,0 +1,71 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: system_config_versions
4
+ #
5
+ # id :bigint not null, primary key
6
+ # transaction_hash :string not null
7
+ # block_number :bigint not null
8
+ # transaction_index :bigint not null
9
+ # supported_contracts :jsonb not null
10
+ # start_block_number :bigint
11
+ # admin_address :string
12
+ # created_at :datetime not null
13
+ # updated_at :datetime not null
14
+ #
15
+ # Indexes
16
+ #
17
+ # idx_on_block_number_transaction_index_efc8dd9c1d (block_number,transaction_index) UNIQUE
18
+ # index_system_config_versions_on_transaction_hash (transaction_hash) UNIQUE
19
+ #
20
+ # Foreign Keys
21
+ #
22
+ # fk_rails_... (block_number => eth_blocks.block_number) ON DELETE => cascade
23
+ # fk_rails_... (transaction_hash => ethscriptions.transaction_hash) ON DELETE => cascade
24
+ #
25
+ class SystemConfigVersion < ActiveRecord::Base # ApplicationRecord
26
+
27
+ belongs_to :ethscription,
28
+ primary_key: 'transaction_hash', foreign_key: 'transaction_hash', optional: true
29
+
30
+ scope :newest_first, -> {
31
+ order(block_number: :desc, transaction_index: :desc)
32
+ }
33
+
34
+ def self.latest_tx_hash
35
+ newest_first.limit(1).pluck(:transaction_hash).first
36
+ end
37
+
38
+ def self.system_mimetype
39
+ "application/vnd.facet.system+json"
40
+ end
41
+
42
+
43
+ def operation_data
44
+ JSON.parse(ethscription.content).fetch('data')
45
+ rescue JSON::ParserError => e
46
+ raise "JSON parse error: #{e.message}"
47
+ end
48
+
49
+
50
+ def self.current
51
+ (newest_first.first || new).freeze
52
+ end
53
+
54
+ =begin
55
+ def as_json(options = {})
56
+ super(
57
+ options.merge(
58
+ only: [
59
+ :supported_contracts,
60
+ :block_number,
61
+ :transaction_index,
62
+ ]
63
+ )
64
+ )
65
+ end
66
+ =end
67
+
68
+ def self.current_admin_address
69
+ current.admin_address || ENV.fetch("INITIAL_SYSTEM_CONFIG_ADMIN_ADDRESS").downcase
70
+ end
71
+ end
@@ -0,0 +1,119 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: transaction_receipts
4
+ #
5
+ # id :bigint not null, primary key
6
+ # transaction_hash :string not null
7
+ # from_address :string not null
8
+ # status :string not null
9
+ # function :string
10
+ # args :jsonb not null
11
+ # logs :jsonb not null
12
+ # block_timestamp :bigint not null
13
+ # error :jsonb
14
+ # to_contract_address :string
15
+ # effective_contract_address :string
16
+ # created_contract_address :string
17
+ # block_number :bigint not null
18
+ # transaction_index :bigint not null
19
+ # block_blockhash :string not null
20
+ # return_value :jsonb
21
+ # runtime_ms :integer not null
22
+ # call_type :string not null
23
+ # gas_price :bigint
24
+ # gas_used :bigint
25
+ # transaction_fee :bigint
26
+ # created_at :datetime not null
27
+ # updated_at :datetime not null
28
+ #
29
+ # Indexes
30
+ #
31
+ # index_contract_tx_receipts_on_block_number_and_tx_index (block_number,transaction_index) UNIQUE
32
+ # index_transaction_receipts_on_block_number (block_number)
33
+ # index_transaction_receipts_on_block_number_and_runtime_ms (block_number,runtime_ms)
34
+ # index_transaction_receipts_on_created_contract_address (created_contract_address)
35
+ # index_transaction_receipts_on_effective_contract_address (effective_contract_address)
36
+ # index_transaction_receipts_on_runtime_ms (runtime_ms)
37
+ # index_transaction_receipts_on_to_contract_address (to_contract_address)
38
+ # index_transaction_receipts_on_transaction_hash (transaction_hash) UNIQUE
39
+ #
40
+ # Foreign Keys
41
+ #
42
+ # fk_rails_... (block_number => eth_blocks.block_number) ON DELETE => cascade
43
+ # fk_rails_... (transaction_hash => ethscriptions.transaction_hash) ON DELETE => cascade
44
+ #
45
+
46
+
47
+ class TransactionReceipt < ActiveRecord::Base # ApplicationRecord
48
+ belongs_to :eth_block, foreign_key: :block_number, primary_key: :block_number
49
+
50
+ belongs_to :contract, primary_key: 'address', foreign_key: 'effective_contract_address', optional: true
51
+ belongs_to :contract_transaction, foreign_key: :transaction_hash, primary_key: :transaction_hash, optional: true
52
+
53
+ belongs_to :ethscription,
54
+ primary_key: 'transaction_hash', foreign_key: 'transaction_hash',
55
+ optional: true
56
+
57
+ scope :newest_first, -> { order(block_number: :desc, transaction_index: :desc) }
58
+ scope :oldest_first, -> { order(block_number: :asc, transaction_index: :asc) }
59
+
60
+
61
+ def contract
62
+ Contract.find_by_address(address)
63
+ end
64
+
65
+ def address
66
+ effective_contract_address
67
+ end
68
+
69
+ def to
70
+ to_contract_address
71
+ end
72
+
73
+ def from
74
+ from_address
75
+ end
76
+
77
+ def contract_address
78
+ created_contract_address
79
+ end
80
+
81
+ def to_or_contract_address
82
+ to || contract_address
83
+ end
84
+
85
+ def as_json(options = {})
86
+ super(
87
+ options.merge(
88
+ only: [
89
+ :transaction_hash,
90
+ :call_type,
91
+ :runtime_ms,
92
+ :block_timestamp,
93
+ :status,
94
+ :function,
95
+ :args,
96
+ :error,
97
+ :logs,
98
+ :block_blockhash,
99
+ :block_number,
100
+ :transaction_index,
101
+ :gas_price,
102
+ :gas_used,
103
+ :transaction_fee,
104
+ :return_value,
105
+ :effective_contract_address
106
+ ],
107
+ methods: [:to, :from, :contract_address, :to_or_contract_address]
108
+ )
109
+ ).with_indifferent_access
110
+ end
111
+
112
+ def failure?
113
+ status.to_s == 'failure'
114
+ end
115
+
116
+ def success?
117
+ status.to_s == 'success'
118
+ end
119
+ end
data/lib/facetq.rb CHANGED
@@ -7,11 +7,18 @@ require 'active_record'
7
7
  ## class ApplicationRecord < ActiveRecord::Base
8
8
  ## end
9
9
 
10
-
11
-
12
- require_relative 'facetq/eth_block'
13
- require_relative 'facetq/ethscription'
14
- require_relative 'facetq/transaction_receipt'
10
+ require_relative 'facetq/json_sorter'
11
+
12
+
13
+ require_relative 'facetq/models/eth_block'
14
+ require_relative 'facetq/models/ethscription'
15
+ require_relative 'facetq/models/transaction_receipt'
16
+ require_relative 'facetq/models/contract'
17
+ require_relative 'facetq/models/contract_call'
18
+ require_relative 'facetq/models/contract_state'
19
+ require_relative 'facetq/models/contract_transaction'
20
+ require_relative 'facetq/models/contract_artifact'
21
+ require_relative 'facetq/models/system_config_version'
15
22
 
16
23
 
17
24
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: facetq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
@@ -58,8 +58,8 @@ dependencies:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '4.0'
61
- description: facetq - "stand-alone" facet (activerecord) models for easy sql database
62
- queries and more
61
+ description: facetq - "stand-alone" facet (activerecord) models for easy (re)use for
62
+ sql database queries and more
63
63
  email: gerald.bauer@gmail.com
64
64
  executables: []
65
65
  extensions: []
@@ -73,9 +73,16 @@ files:
73
73
  - README.md
74
74
  - Rakefile
75
75
  - lib/facetq.rb
76
- - lib/facetq/eth_block.rb
77
- - lib/facetq/ethscription.rb
78
- - lib/facetq/transaction_receipt.rb
76
+ - lib/facetq/json_sorter.rb
77
+ - lib/facetq/models/contract.rb
78
+ - lib/facetq/models/contract_artifact.rb
79
+ - lib/facetq/models/contract_call.rb
80
+ - lib/facetq/models/contract_state.rb
81
+ - lib/facetq/models/contract_transaction.rb
82
+ - lib/facetq/models/eth_block.rb
83
+ - lib/facetq/models/ethscription.rb
84
+ - lib/facetq/models/system_config_version.rb
85
+ - lib/facetq/models/transaction_receipt.rb
79
86
  homepage: https://github.com/0xCompute/rubidity
80
87
  licenses:
81
88
  - Public Domain
@@ -100,6 +107,6 @@ requirements: []
100
107
  rubygems_version: 3.4.10
101
108
  signing_key:
102
109
  specification_version: 4
103
- summary: facetq - "stand-alone" facet (activerecord) models for easy sql database
104
- queries and more
110
+ summary: facetq - "stand-alone" facet (activerecord) models for easy (re)use for sql
111
+ database queries and more
105
112
  test_files: []
@@ -1,39 +0,0 @@
1
-
2
- ## check if applicationrecord works
3
- ## in actierecord "stand-alone" mode??
4
-
5
-
6
- class EthBlock < ActiveRecord::Base # ApplicationRecord
7
-
8
- has_many :ethscriptions, foreign_key: :block_number, primary_key: :block_number
9
- has_many :transaction_receipts, foreign_key: :block_number, primary_key: :block_number
10
-
11
- scope :newest_first, -> { order(block_number: :desc) }
12
- scope :oldest_first, -> { order(block_number: :asc) }
13
-
14
- scope :processed, -> { where.not(processing_state: "pending") }
15
-
16
- def self.max_processed_block_number
17
- EthBlock.processed.maximum(:block_number).to_i
18
- end
19
-
20
-
21
-
22
- def as_json(options = {})
23
- super(options.merge(
24
- only: [
25
- :block_number,
26
- :timestamp,
27
- :blockhash,
28
- :parent_blockhash,
29
- :imported_at,
30
- :processing_state,
31
- :transaction_count,
32
- ]
33
- )).tap do |json|
34
- if association(:transaction_receipts).loaded?
35
- json[:transaction_receipts] = transaction_receipts.map(&:as_json)
36
- end
37
- end.with_indifferent_access
38
- end
39
- end
@@ -1,44 +0,0 @@
1
- class Ethscription < ActiveRecord::Base # ApplicationRecord
2
-
3
- belongs_to :eth_block, foreign_key: :block_number, primary_key: :block_number, optional: true
4
-
5
- # has_many :contracts, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
6
-
7
- has_one :transaction_receipt, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
8
-
9
- # has_one :contract_transaction, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
10
- # has_one :system_config_version, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
11
- # has_many :contract_states, primary_key: 'transaction_hash', foreign_key: 'transaction_hash'
12
-
13
- before_validation :downcase_hex_fields
14
-
15
- scope :newest_first, -> { order(block_number: :desc, transaction_index: :desc) }
16
- scope :oldest_first, -> { order(block_number: :asc, transaction_index: :asc) }
17
-
18
- scope :unprocessed, -> { where(processing_state: "pending") }
19
-
20
- def content
21
- content_uri[/.*?,(.*)/, 1]
22
- end
23
-
24
- def parsed_content
25
- JSON.parse(content)
26
- end
27
-
28
- def processed?
29
- processing_state != "pending"
30
- end
31
-
32
- def self.required_initial_owner
33
- "0x00000000000000000000000000000000000face7"
34
- end
35
-
36
-
37
- private
38
-
39
- def downcase_hex_fields
40
- self.transaction_hash = transaction_hash.downcase
41
- self.creator = creator.downcase
42
- self.initial_owner = initial_owner.downcase
43
- end
44
- end
@@ -1,72 +0,0 @@
1
- class TransactionReceipt < ActiveRecord::Base # ApplicationRecord
2
- belongs_to :eth_block, foreign_key: :block_number, primary_key: :block_number
3
-
4
- # belongs_to :contract, primary_key: 'address', foreign_key: 'effective_contract_address', optional: true
5
- # belongs_to :contract_transaction, foreign_key: :transaction_hash, primary_key: :transaction_hash, optional: true
6
-
7
- belongs_to :ethscription,
8
- primary_key: 'transaction_hash', foreign_key: 'transaction_hash',
9
- optional: true
10
-
11
- scope :newest_first, -> { order(block_number: :desc, transaction_index: :desc) }
12
- scope :oldest_first, -> { order(block_number: :asc, transaction_index: :asc) }
13
-
14
- # def contract
15
- # Contract.find_by_address(address)
16
- # end
17
-
18
- def address
19
- effective_contract_address
20
- end
21
-
22
- def to
23
- to_contract_address
24
- end
25
-
26
- def from
27
- from_address
28
- end
29
-
30
- def contract_address
31
- created_contract_address
32
- end
33
-
34
- def to_or_contract_address
35
- to || contract_address
36
- end
37
-
38
- def as_json(options = {})
39
- super(
40
- options.merge(
41
- only: [
42
- :transaction_hash,
43
- :call_type,
44
- :runtime_ms,
45
- :block_timestamp,
46
- :status,
47
- :function,
48
- :args,
49
- :error,
50
- :logs,
51
- :block_blockhash,
52
- :block_number,
53
- :transaction_index,
54
- :gas_price,
55
- :gas_used,
56
- :transaction_fee,
57
- :return_value,
58
- :effective_contract_address
59
- ],
60
- methods: [:to, :from, :contract_address, :to_or_contract_address]
61
- )
62
- ).with_indifferent_access
63
- end
64
-
65
- def failure?
66
- status.to_s == 'failure'
67
- end
68
-
69
- def success?
70
- status.to_s == 'success'
71
- end
72
- end