transfer100.pizza#71,241,370brc-20mint4.stoe#68,787,320brc-20mint4.stoe#68,787,319brc-20mint4.stoe#68,787,318brc-20mint4.stoe#68,787,317brc-20mint4.stoe#68,787,316brc-20mint4.stoe#68,787,315brc-20mint4.stoe#68,787,314brc-20mint4.stoe#68,787,313brc-20mint4.stoe#68,787,312brc-20mint4.stoe#68,787,311brc-20mint4.stoe#68,787,310brc-20mint4.stoe#68,787,309brc-20mint4.stoe#68,787,308brc-20mint4.stoe#68,787,307brc-20mint4.stoe#68,787,306brc-20mint4.stoe#68,787,305brc-20mint4.stoe#68,787,304brc-20mint4.stoe#68,787,303brc-20mint4.stoe#68,787,302brc-20mint4.stoe#68,787,301brc-20#66,953,763textInscription #59914182#59,914,182webpmint1,000..bet#59,148,933brc-20mint1,000..420#59,085,840brc-20transfer20,000.bdin#53,279,865brc-20transfer3,070,000.turt#52,150,842brc-20#50,141,324vedatransfer124,000.zooa#48,927,541brc-20transfer1,000,000.rait#47,721,903brc-20transfer500,000.rait#46,446,996brc-20transfer500,000.rait#46,446,865brc-20transfer1,575,000.turt#46,270,957brc-20transfer170,000,000.piin#45,060,230brc-20 fn from_instructions( instructions: &mut Instructions, input: usize, offset: usize, ) -> Result<Option<Self>> { if instructions.next().transpose()? != Some(Instruction::Op(opcodes::all::OP_IF)) { return Ok(None); } if instructions.next().transpose()? != Some(Instruction::PushBytes((&PROTOCOL_ID).into())) { return Ok(None); } let mut pushnum = false; let mut payload = Vec::new(); loop { match instructions.next().transpose()? { None => return Ok(None), Some(Instruction::Op(opcodes::all::OP_ENDIF)) => { return Ok(Some(Envelope { input: input.try_into().unwrap(), offset: offset.try_into().unwrap(), payload, pushnum, })); } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_NEG1)) => { pushnum = true; payload.push(vec![0x81]); } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_1)) => { pushnum = true; payload.push(vec![1]); #44,983,270text } fn store(self) -> Self::Value { let mut value = [0; 36]; self.consensus_encode(&mut value.as_mut_slice()).unwrap(); value } } pub(super) type SatPointValue = [u8; 44]; impl Entry for SatPoint { type Value = SatPointValue; fn load(value: Self::Value) -> Self { Decodable::consensus_decode(&mut io::Cursor::new(value)).unwrap() } fn store(self) -> Self::Value { let mut value = [0; 44]; self.consensus_encode(&mut value.as_mut_slice()).unwrap(); value } } pub(super) type SatRange = (u64, u64); impl Entry for SatRange { type Value = [u8; 11]; fn load([b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10]: Self::Value) -> Self { let raw_base = u64::from_le_bytes([b0, b1, b2, b3, b4, b5, b6, 0]); // 51 bit base let base = raw_base & ((1 << 51) - 1); let raw_delta = u64::from_le_bytes([b6, b7, b8, b9, b10, 0, 0, 0]); // 33 bit delta let delta = raw_delta >> 3; (base, base + delta) } fn store(self) -> Self::Value { let base = self.0; #44,983,269text inputs: &[(1, 0, 0, inscription("text/plain", "hello").to_witness())], ..Default::default() }); context.mine_blocks(2); let parent_inscription_id = InscriptionId { txid: parent_txid, index: 0, }; let txid = context.rpc_server.broadcast_tx(TransactionTemplate { inputs: &[ (2, 1, 0, Default::default()), ( 3, 0, 0, Inscription { content_type: Some("text/plain".into()), body: Some("hello".into()), parent: Some(parent_inscription_id.parent_value()), ..Default::default() } .to_witness(), ), ], ..Default::default() }); context.mine_blocks(1); let inscription_id = InscriptionId { txid, index: 0 }; assert_eq!( context.index.get_parent_by_inscription_id(inscription_id), parent_inscription_id ); assert_eq!( context #44,983,267text let delta = self.1 - self.0; let n = u128::from(base) | u128::from(delta) << 51; n.to_le_bytes()[0..11].try_into().unwrap() } } pub(super) type TxidValue = [u8; 32]; impl Entry for Txid { type Value = TxidValue; fn load(value: Self::Value) -> Self { Txid::from_byte_array(value) } fn store(self) -> Self::Value { Txid::to_byte_array(self) } } #[cfg(test)] mod tests { use super::*; #[test] fn inscription_id_entry() { let inscription_id = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdefi0" .parse::<InscriptionId>() .unwrap(); assert_eq!( inscription_id.store(), ( 0x0123456789abcdef0123456789abcdef, 0x0123456789abcdef0123456789abcdef, 0 ) ); assert_eq!( InscriptionId::load(( 0x0123456789abcdef0123456789abcdef, 0x0123456789abcdef0123456789abcdef, 0 )), inscription_id ); } #[test] fn parent_entry_index() { let inscription_id = "0000000000000000000000000000000000000000000000000000000000000000i1" #44,983,265text u32, // timestamp ); impl Default for RuneEntry { fn default() -> Self { Self { burned: 0, divisibility: 0, end: None, etching: Txid::all_zeros(), limit: None, number: 0, rune: Rune(0), supply: 0, symbol: None, timestamp: 0, } } } impl Entry for RuneEntry { type Value = RuneEntryValue; fn load( (burned, divisibility, end, etching, limit, number, rune, supply, symbol, timestamp): RuneEntryValue, ) -> Self { Self { burned, divisibility, end, etching: { let low = etching.0.to_le_bytes(); let high = etching.1.to_le_bytes(); Txid::from_byte_array([ low[0], low[1], low[2], low[3], low[4], low[5], low[6], low[7], low[8], low[9], low[10], low[11], low[12], low[13], low[14], low[15], high[0], high[1], high[2], high[3], high[4], high[5], high[6], high[7], high[8], high[9], high[10], high[11], high[12], high[13], high[14], high[15], ]) #44,983,263textmsgstr "" #: src/guides/explorer.md:37 msgid "Transactions" msgstr "交易" #: src/guides/explorer.md:39 msgid "" "Transactions can be searched by hash, for example, the genesis block " "coinbase transaction:" msgstr "可以通过哈希查找交易,例如创世区块的coinbase交易:" #: src/guides/explorer.md:42 msgid "" "[4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b](https://" "ordinals.com/" "search/4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b)" msgstr "" #: src/guides/explorer.md:44 msgid "Outputs" msgstr "输出" #: src/guides/explorer.md:46 msgid "" "Transaction outputs can searched by outpoint, for example, the only output " "of the genesis block coinbase transaction:" msgstr "可以通过outpoint搜索交易输出,例如创世块coinbase交易的唯一输出:" #: src/guides/explorer.md:49 msgid "" "[4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0](https://" "ordinals.com/" "search/4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0)" msgstr "" #: src/guides/explorer.md:51 msgid "Sats" msgstr "聪" #: src/guides/explorer.md:53 #44,983,260text vec![ParsedEnvelope { payload: Inscription { metadata: Some(vec![0, 1]), duplicate_field: true, ..Default::default() }, ..Default::default() }] ); } #[test] fn pushnum_opcodes_are_parsed_correctly() { const PUSHNUMS: &[(opcodes::All, u8)] = &[ (opcodes::all::OP_PUSHNUM_NEG1, 0x81), (opcodes::all::OP_PUSHNUM_1, 1), (opcodes::all::OP_PUSHNUM_2, 2), (opcodes::all::OP_PUSHNUM_3, 3), (opcodes::all::OP_PUSHNUM_4, 4), (opcodes::all::OP_PUSHNUM_5, 5), (opcodes::all::OP_PUSHNUM_6, 6), (opcodes::all::OP_PUSHNUM_7, 7), (opcodes::all::OP_PUSHNUM_8, 8), (opcodes::all::OP_PUSHNUM_9, 9), (opcodes::all::OP_PUSHNUM_10, 10), (opcodes::all::OP_PUSHNUM_11, 11), (opcodes::all::OP_PUSHNUM_12, 12), (opcodes::all::OP_PUSHNUM_13, 13), (opcodes::all::OP_PUSHNUM_14, 14), (opcodes::all::OP_PUSHNUM_15, 15), (opcodes::all::OP_PUSHNUM_16, 16), ]; for &(op, value) in PUSHNUMS { #44,983,259text .into_iter() .map(|outpoint| OutPoint::new(outpoint.txid, outpoint.vout)) .collect(), ) } #[cfg(test)] fn set_durability(&mut self, durability: redb::Durability) { self.durability = durability; } pub(crate) fn get_unspent_outputs(&self, wallet: Wallet) -> Result<BTreeMap<OutPoint, Amount>> { let mut utxos = BTreeMap::new(); utxos.extend( self .client .list_unspent(None, None, None, None, None)? .into_iter() .map(|utxo| { let outpoint = OutPoint::new(utxo.txid, utxo.vout); let amount = utxo.amount; (outpoint, amount) }), ); let locked_utxos: BTreeSet<OutPoint> = self.get_locked_outputs(wallet)?; for outpoint in locked_utxos { utxos.insert( outpoint, Amount::from_sat( self .client .get_raw_transaction(&outpoint.txid, None)? .output[TryInto::<usize>::try_into(outpoint.vout).unwrap()] .value, ), #44,983,255text leaf_pages: stats.leaf_pages(), branch_pages: stats.branch_pages(), stored_bytes: stats.stored_bytes(), metadata_bytes: stats.metadata_bytes(), fragmented_bytes: stats.fragmented_bytes(), }, ); } let wtx = self.begin_write()?; let stats = wtx.stats()?; let mut tables: BTreeMap<String, TableInfo> = BTreeMap::new(); insert_multimap_table_info(&mut tables, &wtx, SATPOINT_TO_SEQUENCE_NUMBER); insert_multimap_table_info(&mut tables, &wtx, SAT_TO_SEQUENCE_NUMBER); insert_multimap_table_info(&mut tables, &wtx, SEQUENCE_NUMBER_TO_CHILDREN); insert_table_info(&mut tables, &wtx, HEIGHT_TO_BLOCK_HASH); insert_table_info(&mut tables, &wtx, HEIGHT_TO_BLOCK_HASH); insert_table_info(&mut tables, &wtx, HEIGHT_TO_LAST_SEQUENCE_NUMBER); insert_table_info(&mut tables, &wtx, HOME_INSCRIPTIONS); insert_table_info(&mut tables, &wtx, INSCRIPTION_ID_TO_SEQUENCE_NUMBER); insert_table_info(&mut tables, &wtx, INSCRIPTION_NUMBER_TO_SEQUENCE_NUMBER); #44,983,254text Self { height, index } } fn store(self) -> Self::Value { (self.height, self.index) } } #[derive(Debug)] pub(crate) struct InscriptionEntry { pub(crate) charms: u16, pub(crate) fee: u64, pub(crate) height: u32, pub(crate) id: InscriptionId, pub(crate) inscription_number: i32, pub(crate) parent: Option<u32>, pub(crate) sat: Option<Sat>, pub(crate) sequence_number: u32, pub(crate) timestamp: u32, } pub(crate) type InscriptionEntryValue = ( u16, // charms u64, // fee u32, // height InscriptionIdValue, // inscription id i32, // inscription number Option<u32>, // parent Option<u64>, // sat u32, // sequence number u32, // timestamp ); impl Entry for InscriptionEntry { type Value = InscriptionEntryValue; #[rustfmt::skip] fn load( ( charms, fee, height, id, inscription_number, parent, sat, sequence_number, #44,983,252text"explorer, a guide for sat hunters, and a guide to inscriptions." msgstr "请参阅目录以获取指南列表,包括区块浏览器指南、猎聪指南和铭文指南。" #: src/guides/explorer.md:1 msgid "Ordinal Explorer" msgstr "序数浏览器" #: src/guides/explorer.md:4 msgid "" "The `ord` binary includes a block explorer. We host a instance of the block " "explorer on mainnet at [ordinals.com](https://ordinals.com), and on signet " "at [signet.ordinals.com](https://signet.ordinals.com)." msgstr "" "`ord` 文件包含一个区块浏览器。我们的主网区块链器部署在 [ordinals.com]" "(https://ordinals.com), signet部署在[signet.ordinals.com](https://signet." "ordinals.com)." #: src/guides/explorer.md:8 msgid "Running The Explorer" msgstr "运行浏览器" #: src/guides/explorer.md:9 msgid "The server can be run locally with:" msgstr "服务器可以使用本地运行:" #: src/guides/explorer.md:11 msgid "`ord server`" msgstr "" #: src/guides/explorer.md:13 msgid "To specify a port add the `--http-port` flag:" msgstr "指定端口使用`--http-port`标记" #: src/guides/explorer.md:15 msgid "`ord server --http-port 8080`" msgstr "" #: src/guides/explorer.md:17 #44,983,251textuse super::*; #[derive(Copy, Clone, Debug, Display, FromStr, Ord, Eq, Serialize, PartialEq, PartialOrd)] pub(crate) struct Height(pub(crate) u32); impl Height { pub(crate) fn n(self) -> u32 { self.0 } pub(crate) fn subsidy(self) -> u64 { Epoch::from(self).subsidy() } pub(crate) fn starting_sat(self) -> Sat { let epoch = Epoch::from(self); let epoch_starting_sat = epoch.starting_sat(); let epoch_starting_height = epoch.starting_height(); epoch_starting_sat + u64::from(self.n() - epoch_starting_height.n()) * epoch.subsidy() } pub(crate) fn period_offset(self) -> u32 { self.0 % DIFFCHANGE_INTERVAL } } impl Add<u32> for Height { type Output = Self; fn add(self, other: u32) -> Height { Self(self.0 + other) } } impl Sub<u32> for Height { type Output = Self; fn sub(self, other: u32) -> Height { Self(self.0 - other) } } impl PartialEq<u32> for Height { fn eq(&self, other: &u32) -> bool { self.0 == *other } } #[cfg(test)] mod tests { use super::*; #44,983,250text"的钱包,因此 `ord wallet`子命令与 Bitcoin Core 钱包交互。" #: src/guides/inscriptions.md:21 msgid "This guide covers:" msgstr "本指南涵盖:" #: src/guides/inscriptions.md:23 src/guides/inscriptions.md:40 msgid "Installing Bitcoin Core" msgstr "安装 Bitcoin Core" #: src/guides/inscriptions.md:24 msgid "Syncing the Bitcoin blockchain" msgstr "同步比特币区块链" #: src/guides/inscriptions.md:25 msgid "Creating a Bitcoin Core wallet" msgstr "创建 Bitcoin Core 钱包" #: src/guides/inscriptions.md:26 msgid "Using `ord wallet receive` to receive sats" msgstr "使用 `ord wallet receive`收取聪" #: src/guides/inscriptions.md:27 msgid "Creating inscriptions with `ord wallet inscribe`" msgstr "使用`ord wallet inscribe`创建铭文" #: src/guides/inscriptions.md:28 msgid "Sending inscriptions with `ord wallet send`" msgstr "使用 `ord wallet send`发送铭文" #: src/guides/inscriptions.md:29 msgid "Receiving inscriptions with `ord wallet receive`" msgstr "使用`ord wallet receive`收取铭文" #: src/guides/inscriptions.md:30 #, fuzzy msgid "Batch inscribing with `ord wallet inscribe --batch`" #44,983,245text RawEnvelope::from_transaction(transaction) .into_iter() .map(|envelope| envelope.into()) .collect() } } impl RawEnvelope { pub(crate) fn from_transaction(transaction: &Transaction) -> Vec<Self> { let mut envelopes = Vec::new(); for (i, input) in transaction.input.iter().enumerate() { if let Some(tapscript) = input.witness.tapscript() { if let Ok(input_envelopes) = Self::from_tapscript(tapscript, i) { envelopes.extend(input_envelopes); } } } envelopes } fn from_tapscript(tapscript: &Script, input: usize) -> Result<Vec<Self>> { let mut envelopes = Vec::new(); let mut instructions = tapscript.instructions(); while let Some(instruction) = instructions.next() { if instruction? == Instruction::PushBytes((&[]).into()) { if let Some(envelope) = Self::from_instructions(&mut instructions, input, envelopes.len())? { envelopes.push(envelope); } } } Ok(envelopes) } #44,983,244text .into_bytes()])]), Vec::new() ); } #[test] fn ignore_key_path_spends_with_annex() { assert_eq!( parse(&[Witness::from_slice(&[ bitcoin::script::Builder::new() .push_opcode(bitcoin::opcodes::OP_FALSE) .push_opcode(bitcoin::opcodes::all::OP_IF) .push_slice(b"ord") .push_opcode(bitcoin::opcodes::all::OP_ENDIF) .into_script() .into_bytes(), vec![0x50] ])]), Vec::new() ); } #[test] fn parse_from_tapscript() { assert_eq!( parse(&[Witness::from_slice(&[ bitcoin::script::Builder::new() .push_opcode(bitcoin::opcodes::OP_FALSE) .push_opcode(bitcoin::opcodes::all::OP_IF) .push_slice(b"ord") .push_opcode(bitcoin::opcodes::all::OP_ENDIF) .into_script() .into_bytes(), Vec::new() ])]), vec![ParsedEnvelope { ..Default::default() }] ); } #[test] fn ignore_unparsable_scripts() { #44,983,243text#: src/contributing.md:67 msgid "Get help" msgstr "寻求帮助" #: src/contributing.md:70 msgid "" "If you're stuck for more than 15 minutes, ask for help, like a Rust Discord, " "Stack Exchange, or in a project issue or discussion." msgstr "" "如果您遇到困难超过 15 分钟,请寻求帮助,例如 Rust Discord、Stack Exchange,或" "者在项目问题或讨论中寻求帮助。" #: src/contributing.md:73 msgid "Practice hypothesis-driven debugging" msgstr "实践'假说驱动'的调试" #: src/contributing.md:76 msgid "" "Formulate a hypothesis as to what is causing the problem. Figure out how to " "test that hypothesis. Perform that tests. If it works, great, you fixed the " "issue or now you know how to fix the issue. If not, repeat with a new " "hypothesis." msgstr "" "就导致问题的原因提出假设。 弄清楚如何检验该假设。 执行该测试。 如果有效,那太" "好了,您解决了问题,或者现在您知道如何解决问题了。 如果不是,请重复一个新的假" "设。" #: src/contributing.md:81 msgid "Pay attention to error messages" msgstr "关注错误信息" #: src/contributing.md:84 msgid "Read all error messages and don't tolerate warnings." msgstr "阅读所有错误消息,不要容忍警告。" #: src/donate.md:4 msgid "" "Ordinals is open-source and community funded. The current lead maintainer of " #44,983,242textmsgid "" "Sats can be searched by integer, their position within the entire bitcoin " "supply:" msgstr "聪 可以按整数搜索,它们在整个比特币供应中的位置:" #: src/guides/explorer.md:56 msgid "[2099994106992659](https://ordinals.com/search/2099994106992659)" msgstr "" #: src/guides/explorer.md:58 msgid "By decimal, their block and offset within that block:" msgstr "按十进制,它们的块和该块内的偏移量:" #: src/guides/explorer.md:60 msgid "[481824.0](https://ordinals.com/search/481824.0)" msgstr "" #: src/guides/explorer.md:62 msgid "" "By degree, their cycle, blocks since the last halving, blocks since the last " "difficulty adjustment, and offset within their block:" msgstr "" "按度数,他们的周期,自上次减半以来的区块,自上次难度调整以来的区块,以及区块" "内的偏移量:" #: src/guides/explorer.md:65 msgid "[1°0′0″0‴](https://ordinals.com/search/1°0′0″0‴)" msgstr "" #: src/guides/explorer.md:67 msgid "" "By name, their base 26 representation using the letters \"a\" through \"z\":" msgstr "按照名称,它们使用字母\"a\"到\"z\"的 26个字母组合表示:" #: src/guides/explorer.md:69 msgid "[ahistorical](https://ordinals.com/search/ahistorical)" #44,983,240text let txid = context.rpc_server.broadcast_tx(TransactionTemplate { inputs: &[( 2, 1, 0, Inscription { content_type: Some("text/plain".into()), body: Some("hello".into()), parent: Some(parent_inscription_id.parent_value()), ..Default::default() } .to_witness(), )], ..Default::default() }); context.mine_blocks(1); let inscription_id = InscriptionId { txid, index: 0 }; assert_eq!( context.index.get_parent_by_inscription_id(inscription_id), parent_inscription_id ); assert_eq!( context .index .get_children_by_inscription_id(parent_inscription_id) .unwrap(), vec![inscription_id] ); } } #[test] fn parents_can_be_in_preceding_input() { for context in Context::configurations() { context.mine_blocks(1); let parent_txid = context.rpc_server.broadcast_tx(TransactionTemplate { #44,983,239text Epoch(5) } else if sat < Self::STARTING_SATS[7] { Epoch(6) } else if sat < Self::STARTING_SATS[8] { Epoch(7) } else if sat < Self::STARTING_SATS[9] { Epoch(8) } else if sat < Self::STARTING_SATS[10] { Epoch(9) } else if sat < Self::STARTING_SATS[11] { Epoch(10) } else if sat < Self::STARTING_SATS[12] { Epoch(11) } else if sat < Self::STARTING_SATS[13] { Epoch(12) } else if sat < Self::STARTING_SATS[14] { Epoch(13) } else if sat < Self::STARTING_SATS[15] { Epoch(14) } else if sat < Self::STARTING_SATS[16] { Epoch(15) } else if sat < Self::STARTING_SATS[17] { Epoch(16) } else if sat < Self::STARTING_SATS[18] { Epoch(17) } else if sat < Self::STARTING_SATS[19] { Epoch(18) } else if sat < Self::STARTING_SATS[20] { Epoch(19) } else if sat < Self::STARTING_SATS[21] { Epoch(20) } else if sat < Self::STARTING_SATS[22] { Epoch(21) } else if sat < Self::STARTING_SATS[23] { #44,983,237text } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_2)) => { pushnum = true; payload.push(vec![2]); } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_3)) => { pushnum = true; payload.push(vec![3]); } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_4)) => { pushnum = true; payload.push(vec![4]); } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_5)) => { pushnum = true; payload.push(vec![5]); } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_6)) => { pushnum = true; payload.push(vec![6]); } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_7)) => { pushnum = true; payload.push(vec![7]); } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_8)) => { pushnum = true; payload.push(vec![8]); } Some(Instruction::Op(opcodes::all::OP_PUSHNUM_9)) => { pushnum = true; payload.push(vec![9]); #44,983,236text ); } let rtx = self.database.begin_read()?; let outpoint_to_value = rtx.open_table(OUTPOINT_TO_VALUE)?; for outpoint in utxos.keys() { if outpoint_to_value.get(&outpoint.store())?.is_none() { return Err(anyhow!( "output in Bitcoin Core wallet but not in ord index: {outpoint}" )); } } Ok(utxos) } pub(crate) fn get_unspent_output_ranges( &self, wallet: Wallet, ) -> Result<Vec<(OutPoint, Vec<(u64, u64)>)>> { self .get_unspent_outputs(wallet)? .into_keys() .map(|outpoint| match self.list(outpoint)? { Some(List::Unspent(sat_ranges)) => Ok((outpoint, sat_ranges)), Some(List::Spent) => bail!("output {outpoint} in wallet but is spent according to index"), None => bail!("index has not seen {outpoint}"), }) .collect() } pub(crate) fn has_sat_index(&self) -> bool { self.index_sats } pub(crate) fn info(&self) -> Result<Info> { fn insert_table_info<K: RedbKey + 'static, V: RedbValue + 'static>( #44,983,235text .value(); let sequence_number_to_inscription_entry = rtx .open_table(SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY) .unwrap(); let parent_sequence_number = InscriptionEntry::load( sequence_number_to_inscription_entry .get(sequence_number) .unwrap() .unwrap() .value(), ) .parent .unwrap(); let entry = InscriptionEntry::load( sequence_number_to_inscription_entry .get(parent_sequence_number) .unwrap() .unwrap() .value(), ); entry.id } pub(crate) fn get_children_by_sequence_number_paginated( &self, sequence_number: u32, page_size: usize, page_index: usize, ) -> Result<(Vec<InscriptionId>, bool)> { let rtx = self.database.begin_read()?; let sequence_number_to_entry = rtx.open_table(SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY)?; let mut children = rtx .open_multimap_table(SEQUENCE_NUMBER_TO_CHILDREN)? .get(sequence_number)? .skip(page_index * page_size) #44,983,234text }, limit, number, rune: Rune(rune), supply, symbol, timestamp, } } fn store(self) -> Self::Value { ( self.burned, self.divisibility, self.end, { let bytes = self.etching.to_byte_array(); ( u128::from_le_bytes([ bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15], ]), u128::from_le_bytes([ bytes[16], bytes[17], bytes[18], bytes[19], bytes[20], bytes[21], bytes[22], bytes[23], bytes[24], bytes[25], bytes[26], bytes[27], bytes[28], bytes[29], bytes[30], bytes[31], ]), ) }, self.limit, self.number, self.rune.0, self.supply, self.symbol, self.timestamp, ) } } pub(super) type RuneIdValue = (u32, u16); impl Entry for RuneId { type Value = RuneIdValue; fn load((height, index): Self::Value) -> Self { #44,983,233textuse super::*; #[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Serialize, PartialOrd)] pub(crate) struct Epoch(pub(crate) u32); impl Epoch { pub(crate) const STARTING_SATS: [Sat; 34] = [ Sat(0), Sat(1050000000000000), Sat(1575000000000000), Sat(1837500000000000), Sat(1968750000000000), Sat(2034375000000000), Sat(2067187500000000), Sat(2083593750000000), Sat(2091796875000000), Sat(2095898437500000), Sat(2097949218750000), Sat(2098974609270000), Sat(2099487304530000), Sat(2099743652160000), Sat(2099871825870000), Sat(2099935912620000), Sat(2099967955890000), Sat(2099983977420000), Sat(2099991988080000), Sat(2099995993410000), Sat(2099997995970000), Sat(2099998997250000), Sat(2099999497890000), Sat(2099999748210000), Sat(2099999873370000), Sat(2099999935950000), Sat(2099999967240000), Sat(2099999982780000), Sat(2099999990550000), Sat(2099999994330000), Sat(2099999996220000), Sat(2099999997060000), #44,983,231text insert_table_info(&mut tables, &wtx, OUTPOINT_TO_RUNE_BALANCES); insert_table_info(&mut tables, &wtx, OUTPOINT_TO_SAT_RANGES); insert_table_info(&mut tables, &wtx, OUTPOINT_TO_VALUE); insert_table_info(&mut tables, &wtx, RUNE_ID_TO_RUNE_ENTRY); insert_table_info(&mut tables, &wtx, RUNE_TO_RUNE_ID); insert_table_info(&mut tables, &wtx, SAT_TO_SATPOINT); insert_table_info(&mut tables, &wtx, SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY); insert_table_info(&mut tables, &wtx, SEQUENCE_NUMBER_TO_RUNE); insert_table_info(&mut tables, &wtx, SEQUENCE_NUMBER_TO_SATPOINT); insert_table_info(&mut tables, &wtx, STATISTIC_TO_COUNT); insert_table_info(&mut tables, &wtx, TRANSACTION_ID_TO_RUNE); insert_table_info( &mut tables, &wtx, WRITE_TRANSACTION_STARTING_BLOCK_COUNT_TO_TIMESTAMP, ); for table in wtx.list_tables()? { assert!(tables.contains_key(table.name())); } for table in wtx.list_multimap_tables()? { assert!(tables.contains_key(table.name())); #44,983,229text } pub(crate) async fn get_transactions(&self, txids: Vec<Txid>) -> Result<Vec<Transaction>> { if txids.is_empty() { return Ok(Vec::new()); } let mut reqs = Vec::with_capacity(txids.len()); for (i, txid) in txids.iter().enumerate() { let req = json!({ "jsonrpc": "2.0", "id": i, // Use the index as id, so we can quickly sort the response "method": "getrawtransaction", "params": [ txid ] }); reqs.push(req); } let body = Value::Array(reqs).to_string(); let mut results: Vec<JsonResponse<String>>; let mut retries = 0; loop { results = match self.try_get_transactions(body.clone()).await { Ok(results) => results, Err(error) => { if retries >= 5 { return Err(anyhow!( "failed to fetch raw transactions after 5 retries: {}", error )); } log::info!("failed to fetch raw transactions, retrying: {}", error); tokio::time::sleep(tokio::time::Duration::from_millis( #44,983,227text