@@ -73,31 +73,71 @@ class StorageReader
7373 'outputs' => [
7474 { 'name' => '' , 'type' => 'uint256' }
7575 ]
76+ } ,
77+ {
78+ 'name' => 'getEthscriptionWithContent' ,
79+ 'type' => 'function' ,
80+ 'stateMutability' => 'view' ,
81+ 'inputs' => [
82+ { 'name' => 'txHash' , 'type' => 'bytes32' }
83+ ] ,
84+ 'outputs' => [
85+ { 'name' => 'ethscription' , **ETHSCRIPTION_STRUCT_ABI } ,
86+ { 'name' => 'content' , 'type' => 'bytes' }
87+ ]
7688 }
7789 ]
7890
7991 class << self
8092 def get_ethscription_with_content ( tx_hash , block_tag : 'latest' )
81- # Fetch both ethscription data and content in parallel
82- threads = [ ]
83- ethscription_data = nil
84- content_data = nil
93+ # Single call to get both ethscription and content
94+ tx_hash_bytes32 = format_bytes32 ( tx_hash )
8595
86- threads << Thread . new do
87- ethscription_data = get_ethscription ( tx_hash , block_tag : block_tag )
88- end
96+ # Build function signature and encode parameters
97+ function_sig = Eth ::Util . keccak256 ( 'getEthscriptionWithContent(bytes32)' ) [ 0 ...4 ]
8998
90- threads << Thread . new do
91- content_data = get_ethscription_content ( tx_hash , block_tag : block_tag )
92- end
99+ # Encode the parameter (bytes32 is already 32 bytes)
100+ calldata = function_sig + [ tx_hash_bytes32 ] . pack ( 'H*' )
101+
102+ # Make the eth_call
103+ result = eth_call ( '0x' + calldata . unpack1 ( 'H*' ) , block_tag )
104+ raise StandardError , "Ethscription not found: #{ tx_hash } " if result . nil? || result == '0x' || result == '0x0'
105+
106+ # Decode the tuple: (Ethscription, bytes)
107+ types = [ '((bytes32,bytes32,string,string,string,bool),address,address,address,uint256,uint256,uint64,uint64,bytes32)' , 'bytes' ]
108+ decoded = Eth ::Abi . decode ( types , result )
109+
110+ # Extract ethscription struct and content
111+ ethscription_data = decoded [ 0 ]
112+ content_data = decoded [ 1 ]
113+ content_info = ethscription_data [ 0 ] # Nested ContentInfo struct
93114
94- threads . each ( &:join )
115+ {
116+ # ContentInfo fields
117+ content_uri_hash : '0x' + content_info [ 0 ] . unpack1 ( 'H*' ) ,
118+ content_sha : '0x' + content_info [ 1 ] . unpack1 ( 'H*' ) ,
119+ mimetype : content_info [ 2 ] ,
120+ media_type : content_info [ 3 ] ,
121+ mime_subtype : content_info [ 4 ] ,
122+ esip6 : content_info [ 5 ] ,
95123
96- raise StandardError , "Ethscription not found: #{ tx_hash } " unless ethscription_data
124+ # Main Ethscription fields
125+ creator : Eth ::Address . new ( ethscription_data [ 1 ] ) . to_s ,
126+ initial_owner : Eth ::Address . new ( ethscription_data [ 2 ] ) . to_s ,
127+ previous_owner : Eth ::Address . new ( ethscription_data [ 3 ] ) . to_s ,
128+ ethscription_number : ethscription_data [ 4 ] ,
129+ created_at : ethscription_data [ 5 ] ,
130+ l1_block_number : ethscription_data [ 6 ] ,
131+ l2_block_number : ethscription_data [ 7 ] ,
132+ l1_block_hash : '0x' + ethscription_data [ 8 ] . unpack1 ( 'H*' ) ,
97133
98- # Add content to the ethscription data
99- ethscription_data [ :content ] = content_data
100- ethscription_data
134+ # Content
135+ content : content_data
136+ }
137+ rescue => e
138+ Rails . logger . error "Failed to get ethscription with content #{ tx_hash } : #{ e . message } "
139+ Rails . logger . error e . backtrace . join ( "\n " ) if Rails . env . development?
140+ raise e
101141 end
102142
103143 def get_ethscription ( tx_hash , block_tag : 'latest' )
0 commit comments