transfer100.pizza#71,260,085brc-20Inscription #64996459#64,996,459svgreg52013.uniworlds#64,779,214sns#64,010,299Inscription #64010298#64,010,298png"supporting royalties on-chain, thus avoiding the confusion, chaos, and " "negativity of the Ethereum NFT situation." msgstr "" "銘文はこの状況を完全に迴避し、チェーン上のロイヤリティをサポートすることを虚" "偽で約束していません。はイーサリアムNFTのような混乱と消極的な状況を避けまし" "た。" #: src/faq.md:194 msgid "_Inscriptions unlock new markets._" msgstr "_銘文は新たな市場を開きました_" #: src/faq.md:196 msgid "" "Bitcoin's market capitalization and liquidity are greater than Ethereum's by " "a large margin. Much of this liquidity is not available to Ethereum NFTs, " "since many Bitcoiners prefer not to interact with the Ethereum ecosystem due " "to concerns related to simplicity, security, and decentralization." msgstr "" "ビットコインの市場価格と流動性はイーサリアムを大きく上回っている。イーサリア" "ムNFTはこのような流動性の大部分を得ることができません。多くのビットコインユー" "ザーは、シンプルさ、安全性、分散化の観点から、イーサリアムのエコシステムと対" "話することを望んでいないからです。" #: src/faq.md:201 msgid "" "Such Bitcoiners may be more interested in inscriptions than Ethereum NFTs, " "unlocking new classes of collector." msgstr "" "イーサリアムNFTと比較して、そのようなビットコインの支持者は、新しいカテゴリの" "コレクターをロック解除するために、碑文に興味を持っている可能性があります。" #44,986,724text #: src/faq.md:153 msgid "" "Inscriptions, on the other hand, depend on the Bitcoin blockchain, which is " "relatively simple and conservative, and which introduces changes via " "backwards-compatible soft forks." msgstr "" "対照的に、銘文はビットコインブロックチェーンに依存しており、比較的単純で保守" "的であり、後方互換性のあるソフトフォークによって変化を導入しています。" #: src/faq.md:157 msgid "_Inscriptions are more secure._" msgstr "_銘文はより安全です_" #: src/faq.md:159 msgid "" "Inscriptions inherit Bitcoin's transaction model, which allow a user to see " "exactly which inscriptions are being transferred by a transaction before " "they sign it. Inscriptions can be offered for sale using partially signed " "transactions, which don't require allowing a third party, such as an " "exchange or marketplace, to transfer them on the user's behalf." msgstr "" "銘文はビットコインの取引モデルを継承しており、ユーザーは署名する前に取引でど" "の銘文が転送されたかを正確に見ることができる。銘文は署名取引の一部を使用して" "販売することができ、取引所や市場などの第三者がユーザーの代わりにそれらを譲渡" "することを許可する必要はありません。" #: src/faq.md:165 msgid "" "By comparison, Ethereum NFTs are plagued with end-user security " #44,986,712text"thus, potentially less valuable." msgstr "" "一方、イーサリアムNFTは1回の取引でほぼ無限の品質で鋳造することができ、本質的" "にそれほど希少ではないです。そのため、あまり価値がないかもしれません。" #: src/faq.md:181 msgid "_Inscriptions do not pretend to support on-chain royalties._" msgstr "_銘文はチェーン上の版税を支持するふりをしません_" #: src/faq.md:183 msgid "" "On-chain royalties are a good idea in theory but not in practice. Royalty " "payment cannot be enforced on-chain without complex and invasive " "restrictions. The Ethereum NFT ecosystem is currently grappling with " "confusion around royalties, and is collectively coming to grips with the " "reality that on-chain royalties, which were messaged to artists as an " "advantage of NFTs, are not possible, while platforms race to the bottom and " "remove royalty support." msgstr "" "「チェーン上の版税」は理論的には良い考えですが、実際にはうまくいきません。複" "雑で侵入的な制限がなければチェーン上の版税の支払いを強制することはできませ" "ん。イーサリアムNFTエコシステムは、版税をめぐる問題を解決するために努力してい" "ます。そして、は共に一つの現実に直面しています。つまり、NFTチェーン上の版税と" "いう利器を芸術家に伝えることは実際には不可能です。同時に、複数のプラット" "フォームが版税のサポートを削除するために競争しています" #: src/faq.md:190 msgid "" "Inscriptions avoid this situation entirely by making no false promises of " #44,986,704textmsgid "[481824.0](https://ordinals.com/search/481824.0)" msgstr "" #: src/guides/explorer.md:57 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:60 msgid "[1°0′0″0‴](https://ordinals.com/search/1°0′0″0‴)" msgstr "" #: src/guides/explorer.md:62 msgid "" "By name, their base 26 representation using the letters \"a\" through \"z\":" msgstr "名前に応じて、文字\"a\"~\"z\"の26文字の組み合わせで表されます:" #: src/guides/explorer.md:64 msgid "[ahistorical](https://ordinals.com/search/ahistorical)" msgstr "" #: src/guides/explorer.md:66 msgid "" "Or by percentile, the percentage of bitcoin's supply that has been or will " "have been issued when they are mined:" msgstr "" "または百分率で、採掘時にすでに発行された、または発行される予定のビットコイン" "の供給量のパーセント:" #: src/guides/explorer.md:69 msgid "[100%](https://ordinals.com/search/100%)" msgstr "" #: src/guides/inscriptions.md:1 msgid "Ordinal Inscription Guide" #44,986,700text"Bitcoin Core wallet cannot create inscriptions and does not perform sat " "control." msgstr "" "Bitcoin Core ビットコインのフルノードとウォレットを提供します。しかし," "Bitcoin Coreウォレットは碑文を作成できず、スマートコントロールを実行しませ" "ん。" #: src/guides/inscriptions.md:17 msgid "" "This requires [`ord`](https://github.com/ordinals/ord), the ordinal utility. " "`ord` doesn't implement its own wallet, so `ord wallet` subcommands interact " "with Bitcoin Core wallets." msgstr "" "これには['ord'](https://github.com/ordinals/ord),序数ユーティリティ。'ord'は" "自分のウォレットを持っていないので、'ord wallet'サブコマンドはBitcoin Core" "ウォレットと対話します。" #: src/guides/inscriptions.md:21 msgid "This guide covers:" msgstr "このガイドの含まれ:" #: src/guides/inscriptions.md:23 src/guides/inscriptions.md:39 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" #44,986,690textmsgid "" "agrees with the block count on a block explorer like [the mempool.space " "block explorer](https://mempool.space/). `ord` interacts with `bitcoind`, so " "you should leave `bitcoind` running in the background when you're using " "`ord`." msgstr "" "ブロックチェーンブラウザのように[the mempool.space block explorer](https://" "mempool.space/)のようにブロックを記述する...`ord`は'bitcoind'と相互作用するの" "で、'ord'を使用するときは'bitcoind'をバックグラウンドで実行する必要がありま" "す。" #: src/guides/inscriptions.md:88 msgid "Installing `ord`" msgstr " `ord取り付けます。`" #: src/guides/inscriptions.md:91 msgid "" "The `ord` utility is written in Rust and can be built from [source](https://" "github.com/ordinals/ord). Pre-built binaries are available on the [releases " "page](https://github.com/ordinals/ord/releases)." msgstr "" "`ord` プログラムはRust言語で書かれており、[ソースコード](https://github.com/" "ordinals/ord)インストール.事前に作成されたファイルは、[バージョンリリースペー" "ジ](https://github.com/ordinals/ord/releases))からダウンロードできます。" #: src/guides/inscriptions.md:95 msgid "You can install the latest pre-built binary from the command line with:" #44,986,689text"catastrophically when these economic assumptions are no longer met. " "Centralized web servers may disappear at any time." msgstr "" "イーサリアムのNFTコンテンツの中にはチェーン上にあるものもありますが、ほとんど" "のコンテンツはチェーンの下にあり、IP FSやArweaveなどのプラットフォームに保存" "されています。または従来の完全に中心化されたネットワークサーバー上で。IP FSの" "コンテンツは引き続き利用できることを保証していません。IP FSに保存されている" "NFTコンテンツの一部は失われました。Arweaveのようなプラットフォームは弱い経済" "的仮定に依存しており、これらの経済的仮定が満たされなくなったときは壊滅的な失" "敗を起こす可能性が高い。一元化されたネットワークサーバはいつでも消える可能性" "があ。" #: src/faq.md:144 msgid "" "It is very hard for a non-technical user to determine where the content of a " "given Ethereum NFT is stored." msgstr "" "技術ユーザーではない人にとって、イーサリアムNFTのコンテンツがどこに保存されて" "いるかを特定することは困難です。" #: src/faq.md:147 msgid "_Inscriptions are much simpler._" msgstr "_めいぶんはよりかんたんであります_" #: src/faq.md:149 msgid "" "Ethereum NFTs depend on the Ethereum network and virtual machine, which are " "highly complex, constantly changing, and which introduce changes via " "backwards-incompatible hard forks." msgstr "" "イーサリアムNFTはイーサリアムネットワークと仮想マシンに依存しており、高度に複" "雑で変化し続け、下位互換性のないハードフォークによって変化をもたらします。" #44,986,686text"the contract source code is available and has been audited." msgstr "" "技術ユーザーではない人にとって、あるイーサリアムNFTが可変かどうかを判断するこ" "とは困難であり、イーサリアムNFTプラットフォームもNFTが可変かどうかを区別する" "努力をしていません。と、契約ソースコードが利用可能で監査されているかどうかを" "確認します。" #: src/faq.md:130 msgid "_Inscription content is always on-chain._" msgstr "_銘文の内容は永遠にコンタクトします_" #: src/faq.md:132 msgid "" "There is no way for an inscription to refer to off-chain content. This makes " "inscriptions more durable, because content cannot be lost, and scarcer, " "because inscription creators must pay fees proportional to the size of the " "content." msgstr "" "銘文はチェーンの下の内容を引用できない。内容が失われないので、銘文はより長持" "ちします。また、コンテンツのサイズに比例した費用を銘文作成者に支払わなければ" "なりません。" #: src/faq.md:136 msgid "" "Some Ethereum NFT content is on-chain, but much is off-chain, and is stored " "on platforms like IPFS or Arweave, or on traditional, fully centralized web " "servers. Content on IPFS is not guaranteed to continue to be available, and " "some NFT content stored on IPFS has already been lost. Platforms like " "Arweave rely on weak economic assumptions, and will likely fail " #44,986,685textmsgstr "銘文のガイド" #: src/guides/inscriptions.md:4 msgid "" "Individual sats can be inscribed with arbitrary content, creating Bitcoin-" "native digital artifacts that can be held in a Bitcoin wallet and " "transferred using Bitcoin transactions. Inscriptions are as durable, " "immutable, secure, and decentralized as Bitcoin itself." msgstr "" "単一のコングは、ビットコインウォレットに保存され、ビットコイントランザクショ" "ンを使用して転送されるビットコインネイティブデジタルアーティファクトを作成す" "るために、任意のコンテンツを刻印することができます。の銘文はビットコイン自体" "と同じくらい持続的で、不変で、安全で、分散化されています。" #: src/guides/inscriptions.md:9 msgid "" "Working with inscriptions requires a Bitcoin full node, to give you a view " "of the current state of the Bitcoin blockchain, and a wallet that can create " "inscriptions and perform sat control when constructing transactions to send " "inscriptions to another wallet." msgstr "" "銘文を使用するには、ビットコインのブロックチェーンの現在の状態を知ることがで" "きるビットコインの完全なノードが必要です。また、銘文を作成し、取引を構築する" "ことができます」他のウォレットに銘文を送信するときにスマートコントロールを実" "行するウォレット。" #: src/guides/inscriptions.md:14 msgid "" "Bitcoin Core provides both a Bitcoin full node and wallet. However, the " #44,986,684text"long time for larger improvement. Small changes are less likely to " "accumulate merge conflict. As the Athenians said: _The fast commit what they " "will, the slow merge what they must._" msgstr "" "小さな変更は、迅速に作成、レビュー、マージすることができます。これは、永遠に" "作成、レビュー、マージする必要がある大規模なPRの仕事はもっと面白いです。小さ" "な変更にはあまり時間がかからないので、小さな変更の処理を中止する必要がある場" "合は、何時間もの仕事を表す大きな変化に比べて、あまり時間を無駄にしません。迅" "速なPR獲得はプロジェクトをすぐに改善することができます。はより大きな改善を行" "うために長い時間を待つ必要はありません。小さな変更ではマージの競合が累積する" "可能性は低くなります。はアテネ人が言ったように、_速い者はその望みを尽くし、遅" "い者はその必要を併合します。_" #: 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 " #44,986,683text"you must specify the cookie file location. If you are using a custom data " "directory (specifying the `datadir` option), then you must specify the " "cookie location like `bitcoin-cli -rpccookiefile=<your_bitcoin_datadir>/." "cookie -getinfo`. When running `ord` you must specify the cookie file " "location with `--cookie-file=<your_bitcoin_datadir>/.cookie`." msgstr "" "`bitcoin-cli -getinfo`가 `Could not locate RPC credentials`을 반환하면 쿠키 " "파일 위치를 지정해야 한다. 사용자 지정 데이터 디렉터리를 사용하는 경우" "(`datadir` 옵션을 지정) `bitcoin-cli -rpccookiefile=<your_bitcoin_datadir>/." "cookie -getinfo`와 같이 쿠키 위치를 지정해야 한다. `ord`을 실행할 때는 `--" "cookie-file=<your_bitcoin_datadir>/.cookie`로 쿠키 파일 위치를 지정해야 한다." #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:118 msgid "" "Make sure you do _NOT_ have `disablewallet=1` in your `bitcoin.conf` file. " "If `bitcoin-cli listwallets` returns `Method not found` then the wallet is " "disabled and you won't be able to use `ord`." msgstr "" "`bitcoin.conf` 파일에 `disablewallet=1`이 _없는_ 것을 확인하자. `bitcoin-cli " #44,986,651textmsgstr "또는 `-txindex`와 함께 `bitcoind`를 실행한다:" #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:69 msgid "" "Details on creating or modifying your `bitcoin.conf` file can be found [here]" "(https://github.com/bitcoin/bitcoin/blob/master/doc/bitcoin-conf.md)." msgstr "" "`bitcoin.conf` 파일 생성 또는 수정에 대한 자세한 내용은 [여기](https://" "github.com/bitcoin/bitcoin/blob/master/doc/bitcoin-conf.md)에서 확인할 수 있" "다." #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:72 msgid "Syncing the Bitcoin Blockchain" msgstr "비트코인 블록체인 동기화" #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:75 msgid "To sync the chain, run:" msgstr "체인을 동기화하려면 다음을 실행한다:" #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:81 msgid "…and leave it running until `getblockcount`:" msgstr "...그리고 `getblockcount`가:" #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:87 msgid "" "agrees with the block count on a block explorer like [the mempool.space " "block explorer](https://mempool.space/). `ord` interacts with `bitcoind`, so " "you should leave `bitcoind` running in the background when you're using " #44,986,649text"`ord`." msgstr "" "[mempool.space block explorer](https://mempool.space/)와 같은 블록 탐색기의 " "블록 수와 일치할때까지 실행한다. `ord`는 `bitcoind`와 상호 작용하므로 `ord`" "을 사용할 때는 `bitcoind`를 백그라운드에서 실행하도록 두어야 한다." #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:91 msgid "" "The blockchain takes about 600GB of disk space. If you have an external " "drive you want to store blocks on, use the configuration option " "`blocksdir=<external_drive_path>`. This is much simpler than using the " "`datadir` option because the cookie file will still be in the default " "location for `bitcoin-cli` and `ord` to find." msgstr "" "블록체인은 약 600GB의 디스크 공간을 필요로 한다. 블록을 저장할 외장 드라이브" "가 있는 경우, 설정 옵션 `blocksdir=<external_drive_path>`를 사용한다. 이렇게 " "하면 쿠키 파일이 여전히 `bitcoin-cli`와 `ord`가 찾을 수 있는 기본 위치에 있" "기 때문에 `datadir` 옵션을 사용하는 것보다 훨씬 간단하다." #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:97 #: /workspaces/ord_ko/docs/src/guides/collecting/sparrow-wallet.md:173 msgid "Troubleshooting" msgstr "트러블 슈팅" #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:100 #44,986,646textmsgid "" "Make sure you can access `bitcoind` with `bitcoin-cli -getinfo` and that it " "is fully synced." msgstr "" "`bitcoind`를 `bitcoin-cli -getinfo`로 액세스할 수 있는지 그리고 이것이 완전" "히 동기화되었는지를 확인한다." #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:103 msgid "" "If `bitcoin-cli -getinfo` returns `Could not connect to the server`, " "`bitcoind` is not running." msgstr "" "`bitcoin-cli -getinfo`가 `Could not connect to the server`을 반환하면 " "`bitcoind`가 실행되고 있지 않은 것이다." #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:106 msgid "" "Make sure `rpcuser`, `rpcpassword`, or `rpcauth` are _NOT_ set in your " "`bitcoin.conf` file. `ord` requires using cookie authentication. Make sure " "there is a file `.cookie` in your bitcoin data directory." msgstr "" "`rpcuser`, `rpcpassword` 또는 `rpcauth`가 `bitcoin.conf` 파일에 설정되어 있" "지 _않는_ 것을 확인하자. `ord`는 쿠키 인증에 사용을 요구한다. 비트코인 데이" "터 디렉토리에 `.cookie` 파일이 있는지 확인하자." #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:110 msgid "" "If `bitcoin-cli -getinfo` returns `Could not locate RPC credentials`, then " #44,986,645textmsgid "" "This guide does not cover installing Bitcoin Core in detail. Once Bitcoin " "Core is installed, you should be able to run `bitcoind -version` " "successfully from the command line. Do _NOT_ use `bitcoin-qt`." msgstr "" "이 가이드에서는 Bitcoin Core 설치에 대해 자세히 다루지 않는다. Bitcoin Core" "가 설치되면 명령줄에서 `bitcoind -version`을 성공적으로 실행할 수 있어야 한" "다. `bitcoin-qt`는 사용하지 말라." #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:51 msgid "Configuring Bitcoin Core" msgstr "Bitcoin Core 설정하기" #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:54 msgid "`ord` requires Bitcoin Core's transaction index and rest interface." msgstr "`ord`는 Bitcoin Core의 트랜잭션 인덱스와 rest 인터페이스가 필요하다." #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:56 msgid "" "To configure your Bitcoin Core node to maintain a transaction index, add the " "following to your `bitcoin.conf`:" msgstr "" "트랜잭션 인덱스를 유지하도록 Bitcoin Core 노드를 설정하려면, `bitcoin.conf`" "에 다음을 추가한다:" #: /workspaces/ord_ko/docs/src/guides/inscriptions.md:63 msgid "Or, run `bitcoind` with `-txindex`:" #44,986,644textchecksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" dependencies = [ "jobserver", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "time 0.1.45", "wasm-bindgen", "winapi", ] [[package]] name = "ciborium" #44,986,491textsource = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1906889b1f805a715eac02b2dea416e25c5cfa00f099530fa9d137a3cff93113" dependencies = [ "darling 0.20.3", "mime", "new_mime_guess", "proc-macro2", "quote", "syn 2.0.27", ] [[package]] name = "brotli" version = "3.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", "brotli-decompressor", ] [[package]] name = "brotli-decompressor" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", ] [[package]] name = "bumpalo" version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" #44,986,490textchecksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes 0.11.0", "serde", "unicode-normalization", ] [[package]] name = "bitcoin" version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e99ff7289b20a7385f66a0feda78af2fc119d28fb56aea8886a9cd0a4abdd75" dependencies = [ "bech32", "bitcoin-private", "bitcoin_hashes 0.12.0", "hex_lit", "secp256k1", "serde", ] [[package]] name = "bitcoin-private" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" [[package]] name = "bitcoin_hashes" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" [[package]] name = "bitcoin_hashes" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" #44,986,489text <li role="none"><button role="menuitem" class="theme"> <a id="en">English</a> </button></li> <li role="none"><button role="menuitem" class="theme"> <a id="de">Deutsch</a> </button></li> <li role="none"><button role="menuitem" class="theme"> <a id="fr">Français</a> </button></li> <li role="none"><button role="menuitem" class="theme"> <a id="es">Español</a> </button></li> <li role="none"><button role="menuitem" class="theme"> <a id="pt">Português</a> </button></li> <li role="none"><button role="menuitem" class="theme"> <a id="ru">Русский</a> </button></li> #44,986,488text <div id="body-container"> <!-- Provide site root to javascript --> <script> var path_to_root = "{{ path_to_root }}"; var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}"; </script> <!-- Work around some values being stored in localStorage wrapped in quotes --> <script> try { var theme = localStorage.getItem('mdbook-theme'); var sidebar = localStorage.getItem('mdbook-sidebar'); if (theme.startsWith('"') && theme.endsWith('"')) { localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1)); } if (sidebar.startsWith('"') && sidebar.endsWith('"')) { localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1)); } } catch (e) { } </script> <!-- Set the theme before any content is loaded, prevents flash --> #44,986,487text] [[package]] name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encode_unicode" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if", ] [[package]] name = "env_logger" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ "humantime", "is-terminal", "log", "regex", "termcolor", ] [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" #44,986,481text "futures-sink", "futures-task", "futures-util", ] [[package]] name = "futures-channel" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", ] [[package]] name = "futures-core" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", "futures-util", ] [[package]] name = "futures-io" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-lite" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" #44,986,476textchecksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "flate2" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", "miniz_oxide", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] [[package]] name = "futures" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", "futures-executor", "futures-io", #44,986,474textchecksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ "fastrand 1.9.0", "futures-core", "futures-io", "memchr", "parking", "pin-project-lite", "waker-fn", ] [[package]] name = "futures-macro" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", "syn 2.0.27", ] [[package]] name = "futures-rustls" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" dependencies = [ "futures-io", "rustls", ] [[package]] name = "futures-sink" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" #44,986,472textdependencies = [ "block-buffer", "crypto-common", ] [[package]] name = "diligent-date-parser" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6cf7fe294274a222363f84bcb63cdea762979a0443b4cf1f4f8fd17c86b1182" dependencies = [ "chrono", ] [[package]] name = "dirs" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", "option-ext", "redox_users", "windows-sys 0.48.0", ] [[package]] name = "displaydoc" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", "syn 2.0.27", #44,986,471text op_return: Some( Runestone { edicts: vec![Edict { id: 0, amount: u128::max_value(), output: 0, }], etching: Some(Etching { rune: Rune(RUNE), ..Default::default() }), ..Default::default() } .encipher(), ), ..Default::default() }); context.mine_blocks(1); let id0 = RuneId { height: 2, index: 1, }; context.assert_runes( [( id0, RuneEntry { etching: txid0, rune: Rune(RUNE), supply: u128::max_value(), timestamp: 2, ..Default::default() }, )], [( OutPoint { txid: txid0, vout: 0, }, vec![(id0, u128::max_value())], )], ); let txid1 = context.rpc_server.broadcast_tx(TransactionTemplate { inputs: &[(2, 0, 0, Witness::new())], op_return: Some( Runestone { edicts: vec![Edict { #44,985,502text id: 0, amount: u128::max_value(), output: 0, }], etching: Some(Etching { rune: Rune(RUNE + 1), ..Default::default() }), ..Default::default() } .encipher(), ), ..Default::default() }); context.mine_blocks(1); let id1 = RuneId { height: 3, index: 1, }; context.assert_runes( [ ( id0, RuneEntry { etching: txid0, rune: Rune(RUNE), supply: u128::max_value(), timestamp: 2, ..Default::default() }, ), ( id1, RuneEntry { etching: txid1, rune: Rune(RUNE + 1), supply: u128::max_value(), timestamp: 3, number: 1, ..Default::default() }, ), ], [ ( OutPoint { txid: txid0, vout: 0, }, #44,985,497textuse super::*; #[derive(Boilerplate)] pub(crate) struct RangeHtml { pub(crate) start: Sat, pub(crate) end: Sat, } impl PageContent for RangeHtml { fn title(&self) -> String { format!("Sat range {}–{}", self.start, self.end) } } #[cfg(test)] mod tests { use super::*; #[test] fn range_html() { pretty_assert_eq!( RangeHtml { start: Sat(0), end: Sat(1), } .to_string(), " <h1>Sat range 0–1</h1> <dl> <dt>value</dt><dd>1</dd> <dt>first</dt><dd><a href=/sat/0 class=mythic>0</a></dd> </dl> " .unindent() ); } #[test] fn bugfix_broken_link() { pretty_assert_eq!( RangeHtml { start: Sat(1), end: Sat(10), } .to_string(), " <h1>Sat range 1–10</h1> <dl> <dt>value</dt><dd>9</dd> <dt>first</dt><dd><a href=/sat/1 class=common>1</a></dd> </dl> " .unindent() ); } } #44,985,496textuse super::*; #[derive(Boilerplate)] pub(crate) struct RuneHtml { pub(crate) entry: RuneEntry, pub(crate) id: RuneId, pub(crate) parent: Option<InscriptionId>, } impl PageContent for RuneHtml { fn title(&self) -> String { format!("Rune {}", self.entry.rune) } } #[cfg(test)] mod tests { use {super::*, crate::runes::Rune}; #[test] fn display() { assert_regex_match!( RuneHtml { entry: RuneEntry { burned: 123456789123456789, divisibility: 9, etching: Txid::all_zeros(), number: 25, rune: Rune(u128::max_value()), supply: 123456789123456789, symbol: Some('$'), limit: Some(1000000001), end: Some(11), timestamp: 0, }, id: RuneId { height: 10, index: 9, }, parent: Some(InscriptionId { txid: Txid::all_zeros(), index: 0, }), }, r"<h1>BCGDENLQRQWDSLRUGSNLBTMFIJAV</h1> <iframe .* src=/preview/0{64}i0></iframe> #44,985,493text etching: Some(Etching { rune: Rune(RUNE), ..Default::default() }), ..Default::default() } .encipher(), ), ..Default::default() }); context.mine_blocks(1); let id = RuneId { height: 2, index: 1, }; context.assert_runes( [( id, RuneEntry { etching: txid0, rune: Rune(RUNE), supply: u128::max_value(), timestamp: 2, ..Default::default() }, )], [( OutPoint { txid: txid0, vout: 0, }, vec![(id, u128::max_value())], )], ); let txid = context.rpc_server.broadcast_tx(TransactionTemplate { inputs: &[(2, 1, 0, Witness::new())], op_return: Some( script::Builder::new() .push_opcode(opcodes::all::OP_RETURN) .into_script(), ), op_return_index: Some(0), ..Default::default() }); context.mine_blocks(1); #44,985,491text ..Default::default() }, ), ( id1, RuneEntry { etching: txid1, rune: Rune(RUNE + 1), supply: u128::max_value(), timestamp: 3, number: 1, ..Default::default() }, ), ], [( OutPoint { txid: txid2, vout: 0, }, vec![(id0, u128::max_value()), (id1, u128::max_value())], )], ); } #[test] fn unallocated_runes_are_assigned_to_first_non_op_return_output_when_op_return_is_not_last_output( ) { let context = Context::builder() .arg("--index-runes-pre-alpha-i-agree-to-get-rekt") .build(); context.mine_blocks(1); let txid0 = context.rpc_server.broadcast_tx(TransactionTemplate { inputs: &[(1, 0, 0, Witness::new())], op_return: Some( Runestone { edicts: vec![Edict { id: 0, amount: u128::max_value(), output: 0, }], #44,985,480text <link rel=stylesheet href=/static/index.css> <link rel=stylesheet href=/static/modern-normalize.css> <script src=/static/index.js defer></script> </head> <body> <header> <nav> <a href=/ title=home>Ordinals<sup>alpha</sup></a> .* <a href=/clock title=clock>.*</a> <a href=/rare.txt title=rare>.*</a> .* <form action=/search method=get> <input type=text .*> <input class=icon type=image .*> </form> </nav> </header> <main> <h1>Foo</h1> </main> </body> </html> " ); } #[test] fn page_mainnet() { assert_regex_match!( Foo.page(Arc::new(PageConfig { chain: Chain::Mainnet, csp_origin: None, domain: None, index_sats: true, })), r".*<nav>\s*<a href=/ title=home>Ordinals<sup>alpha</sup></a>.*" ); } #[test] fn page_no_sat_index() { assert_regex_match!( Foo.page(Arc::new(PageConfig { chain: Chain::Mainnet, csp_origin: None, domain: None, #44,985,479text }, ), ], [( OutPoint { txid: txid2, vout: 0, }, vec![(id0, u128::max_value()), (id1, u128::max_value())], )], ); let txid3 = context.rpc_server.broadcast_tx(TransactionTemplate { inputs: &[(4, 1, 0, Witness::new())], outputs: 2, op_return: Some( Runestone { edicts: vec![ Edict { id: id0.into(), amount: u128::max_value() / 2, output: 1, }, Edict { id: id1.into(), amount: u128::max_value() / 2, output: 1, }, ], ..Default::default() } .encipher(), ), ..Default::default() }); context.mine_blocks(1); context.assert_runes( [ ( id0, RuneEntry { etching: txid0, rune: Rune(RUNE), supply: u128::max_value(), timestamp: 2, ..Default::default() #44,985,478text None } } #[cfg(test)] mod tests { use super::*; struct Foo; impl Display for Foo { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "<h1>Foo</h1>") } } impl PageContent for Foo { fn title(&self) -> String { "Foo".to_string() } } #[test] fn page() { assert_regex_match!( Foo.page(Arc::new(PageConfig { chain: Chain::Mainnet, csp_origin: Some("https://signet.ordinals.com".into()), domain: Some("signet.ordinals.com".into()), index_sats: true, }),), r"<!doctype html> <html lang=en> <head> <meta charset=utf-8> <meta name=format-detection content='telephone=no'> <meta name=viewport content='width=device-width,initial-scale=1.0'> <meta property=og:title content='Foo'> <meta property=og:image content='https://signet.ordinals.com/static/favicon.png'> <meta property=twitter:card content=summary> <title>Foo</title> <link rel=alternate href=/feed.xml type=application/rss\+xml title='Inscription RSS Feed'> #44,985,476textuse super::*; #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewAudioHtml { pub(crate) inscription_id: InscriptionId, } #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewCodeHtml { pub(crate) inscription_id: InscriptionId, pub(crate) language: media::Language, } #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewFontHtml { pub(crate) inscription_id: InscriptionId, } #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewImageHtml { pub(crate) inscription_id: InscriptionId, } #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewMarkdownHtml { pub(crate) inscription_id: InscriptionId, } #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewModelHtml { pub(crate) inscription_id: InscriptionId, } #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewPdfHtml { pub(crate) inscription_id: InscriptionId, } #[derive(boilerplate::Boilerplate)] pub(crate) struct PreviewTextHtml { pub(crate) inscription_id: InscriptionId, } #[derive(boilerplate::Boilerplate)] #44,985,475textTesting ======= Ord can be tested using the following flags to specify the test network. For more information on running Bitcoin Core for testing, see [Bitcoin's developer documentation](https://developer.bitcoin.org/examples/testing.html). Most `ord` commands in [inscriptions](inscriptions.md) and [explorer](explorer.md) can be run with the following network flags: | Network | Flag | |---------|------| | Testnet | `--testnet` or `-t` | | Signet | `--signet` or `-s` | | Regtest | `--regtest` or `-r` | Regtest doesn't require downloading the blockchain or indexing ord. Example ------- Run bitcoind in regtest with: ``` bitcoind -regtest -txindex ``` Create a wallet in regtest with: ``` ord -r wallet create ``` Get a regtest receive address with: ``` ord -r wallet receive ``` Mine 101 blocks (to unlock the coinbase) with: ``` bitcoin-cli -regtest generatetoaddress 101 <receive address> ``` Inscribe in regtest with: ``` ord -r wallet inscribe --fee-rate 1 --file <file> ``` Mine the inscription with: ``` bitcoin-cli -regtest generatetoaddress 1 <receive address> #44,985,404text Each time you want to receive you should use a brand-new address, and not re-use existing addresses. Note that bitcoin is different to some other blockchain wallets, in that this wallet can generate an unlimited number of new addresses. You can generate a new address by clicking on the `Get Next Address` button. You can see all of your addresses in the `Addresses` tab of the app. You can add a label to each address, so you can keep track of what it was used for. ![](images/wallet_setup_08.png) ## Validating / Viewing Received Inscriptions Once you have received an inscription you will see a new transaction in the `Transactions` tab of Sparrow, as well as a new UTXO in the `UTXOs` tab. Initially this transaction may have an "Unconfirmed" status, and you will need to wait for it to be mined into a bitcoin block before it is fully received. ![](images/validating_viewing_01.png) To track the status of your transaction you can right-click on it, select `Copy Transaction ID` and then paste that transaction id into [mempool.space](https://mempool.space). #44,985,399textadditionally receive the witness discount, making inscription content storage relatively economical. Since taproot script spends can only be made from existing taproot outputs, inscriptions are made using a two-phase commit/reveal procedure. First, in the commit transaction, a taproot output committing to a script containing the inscription content is created. Second, in the reveal transaction, the output created by the commit transaction is spent, revealing the inscription content on-chain. Inscription content is serialized using data pushes within unexecuted conditionals, called "envelopes". Envelopes consist of an `OP_FALSE OP_IF … OP_ENDIF` wrapping any number of data pushes. Because envelopes are effectively no-ops, they do not change the semantics of the script in which they are included, and can be combined with any other locking script. A text inscription containing the string "Hello, world!" is serialized as follows: ``` OP_FALSE OP_IF OP_PUSH "ord" OP_PUSH 1 OP_PUSH "text/plain;charset=utf-8" #44,985,397text ![](images/wallet_setup_01.png) Change the `Script Type` to `Taproot (P2TR)` and select the `New or Imported Software Wallet` option. ![](images/wallet_setup_02.png) Select `Use 12 Words` and then click `Generate New`. Leave the passphrase blank. ![](images/wallet_setup_03.png) A new 12 word BIP39 seed phrase will be generated for you. Write this down somewhere safe as this is your backup to get access to your wallet. NEVER share or show this seed phrase to anyone else. Once you have written down the seed phrase click `Confirm Backup`. ![](images/wallet_setup_04.png) Re-enter the seed phrase which you wrote down, and then click `Create Keystore`. ![](images/wallet_setup_05.png) Click `Import Keystore`. ![](images/wallet_setup_06.png) Click `Apply`. Add a password for the wallet if you want to. ![](images/wallet_setup_07.png) You now have a wallet which is compatible with `ord`, and can be imported into `ord` using the BIP39 Seed Phrase. To receive ordinals or inscriptions, click on the `Receive` tab and copy a new address. #44,985,396text ![](images/validating_viewing_02.png) Once the transaction has confirmed, you can validate and view your inscription by heading over to the `UTXOs` tab, finding the UTXO you want to check, right-clicking on the `Output` and selecting `Copy Transaction Output`. This transaction output id can then be pasted into the [ordinals.com](https://ordinals.com) search. ## Freezing UTXO's As explained above, each of your inscriptions is stored in an Unspent Transaction Output (UTXO). You want to be very careful not to accidentally spend your inscriptions, and one way to make it harder for this to happen is to freeze the UTXO. To do this, go to the `UTXOs` tab, find the UTXO you want to freeze, right-click on the `Output` and select `Freeze UTXO`. This UTXO (Inscription) is now un-spendable within the Sparrow Wallet until you unfreeze it. ## Importing into `ord` wallet For details on setting up Bitcoin Core and the `ord` wallet check out the [Inscriptions Guide](../inscriptions.md) When setting up `ord`, instead of running `ord wallet create` to create a brand-new wallet, you can import your existing wallet using `ord wallet restore "BIP39 SEED PHRASE"` using the seed phrase you generated with Sparrow Wallet. #44,985,390text You should add a label for the recipient address, a label like `alice address for inscription #123` would be ideal. Once you have checked the transaction is a safe transaction using the checks above, and you are confident to send it you can click `Create Transaction`. ![](images/sending_03.png) Here again you can double check that your transaction looks safe, and once you are confident you can click `Finalize Transaction for Signing`. ![](images/sending_04.png) Here you can triple check everything before hitting `Sign`. ![](images/sending_05.png) And then actually you get very very last chance to check everything before hitting `Broadcast Transaction`. Once you broadcast the transaction it is sent to the bitcoin network, and starts being propagated into the mempool. ![](images/sending_06.png) If you want to track the status of your transaction you can copy the `Transaction Id (Txid)` and paste that into [mempool.space](https://mempool.space) Once the transaction has confirmed you can check the inscription page on [ordinals.com](https://ordinals.com) to validate that it has moved to the new output location and address. #44,985,388textCollecting Inscriptions and Ordinals with Sparrow Wallet ===================== Users who cannot or have not yet set up the [ord](https://github.com/ordinals/ord) wallet can receive inscriptions and ordinals with alternative bitcoin wallets, as long as they are _very_ careful about how they spend from that wallet. This guide gives some basic steps on how to create a wallet with [Sparrow Wallet](https://sparrowwallet.com/) which is compatible with `ord` and can be later imported into `ord` ## ⚠️⚠️ Warning!! ⚠️⚠️ As a general rule if you take this approach, you should use this wallet with the Sparrow software as a receive-only wallet. Do not spend any satoshis from this wallet unless you are sure you know what you are doing. You could very easily inadvertently lose access to your ordinals and inscriptions if you don't heed this warning. ## Wallet Setup & Receiving Download the Sparrow Wallet from the [releases page](https://sparrowwallet.com/download/) for your particular operating system. Select `File -> New Wallet` and create a new wallet called `ord`. #44,985,387textModeration ========== `ord` includes a block explorer, which you can run locally with `ord server`. The block explorer allows viewing inscriptions. Inscriptions are user-generated content, which may be objectionable or unlawful. It is the responsibility of each individual who runs an ordinal block explorer instance to understand their responsibilities with respect to unlawful content, and decide what moderation policy is appropriate for their instance. In order to prevent particular inscriptions from being displayed on an `ord` instance, they can be included in a YAML config file, which is loaded with the `--config` option. To hide inscriptions, first create a config file, with the inscription ID you want to hide: ```yaml hidden: - 0000000000000000000000000000000000000000000000000000000000000000i0 ``` The suggested name for `ord` config files is `ord.yaml`, but any filename can be used. Then pass the file to `--config` when starting the server: `ord --config ord.yaml server` Note that the `--config` option comes after `ord` but before the `server` #44,985,381textand `N` is the index of the inscription in the reveal transaction. The commit transaction commits to a tapscript containing the content of the inscription, and the reveal transaction spends from that tapscript, revealing the content on chain and inscribing it on the first sat of the input that contains the corresponding tapscript. Wait for the reveal transaction to be mined. You can check the status of the commit and reveal transactions using [the mempool.space block explorer](https://mempool.space/). Once the reveal transaction has been mined, the inscription ID should be printed when you run: ``` ord wallet inscriptions ``` Parent-Child Inscriptions ------------------------- Parent-child inscriptions enable what is colloquially known as collections, see [provenance](../inscriptions/provenance.md) for more information. To make an inscription a child of another, the parent inscription has to be inscribed and present in the wallet. To choose a parent run `ord wallet inscriptions` and copy the inscription id (`<PARENT_INSCRIPTION_ID>`). #44,985,380textcontent, the higher the fee that the inscription transaction must pay. Inscription content is included in transaction witnesses, which receive the witness discount. To calculate the approximate fee that an inscribe transaction will pay, divide the content size by four and multiply by the fee rate. Inscription transactions must be less than 400,000 weight units, or they will not be relayed by Bitcoin Core. One byte of inscription content costs one weight unit. Since an inscription transaction includes not just the inscription content, limit inscription content to less than 400,000 weight units. 390,000 weight units should be safe. Creating Inscriptions --------------------- To create an inscription with the contents of `FILE`, run: ``` ord wallet inscribe --fee-rate FEE_RATE --file FILE ``` Ord will output two transactions IDs, one for the commit transaction, and one for the reveal transaction, and the inscription ID. Inscription IDs are of the form `TXIDiN`, where `TXID` is the transaction ID of the reveal transaction,#44,985,379textuse {super::*, sha3::Digest, sha3::Keccak256}; #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct Ethereum(String); impl From<InscriptionId> for Ethereum { fn from(inscription_id: InscriptionId) -> Self { let mut array = [0; 36]; let (txid, index) = array.split_at_mut(32); txid.copy_from_slice(inscription_id.txid.as_ref()); index.copy_from_slice(&inscription_id.index.to_be_bytes()); let digest = bitcoin::hashes::sha256::Hash::hash(&array); Self(create_address_with_checksum(&hex::encode(&digest[0..20]))) } } impl Display for Ethereum { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}", self.0) } } /// Given the hex digits of an Ethereum address, return that address with a /// checksum as per https://eips.ethereum.org/EIPS/eip-55 fn create_address_with_checksum(address: &str) -> String { assert_eq!(address.len(), 40); assert!(address .chars() .all(|c| c.is_ascii_hexdigit() && (!c.is_alphabetic() || c.is_lowercase()))); let hash = hex::encode(&Keccak256::digest(address.as_bytes())[..20]); #44,985,357text "2222222222222222222222222222222222222222222222222222222222222222" .parse() .unwrap() ), ( 1260001, "1111111111111111111111111111111111111111111111111111111111111111" .parse() .unwrap() ), ( 1260000, "0000000000000000000000000000000000000000000000000000000000000000" .parse() .unwrap() ) ], feature_blocks, ) .to_string() .unindent(), "<h1>Blocks</h1> <div class=block> <h2><a href=/block/1260002>Block 1260002</a></h2> <div class=thumbnails> <a href=/inscription/1{64}i1><iframe .* src=/preview/1{64}i1></iframe></a> <a href=/inscription/2{64}i2><iframe .* src=/preview/2{64}i2></iframe></a> </div> </div> <ol start=1260001 reversed class=block-list> <li><a href=/block/1{64}>1{64}</a></li> <li><a href=/block/0{64}>0{64}</a></li> #44,985,356textuse super::*; #[derive(Boilerplate)] pub(crate) struct HomeHtml { pub(crate) inscriptions: Vec<InscriptionId>, } impl PageContent for HomeHtml { fn title(&self) -> String { "Ordinals".to_string() } } #[cfg(test)] mod tests { use super::*; #[test] fn html() { assert_regex_match!( HomeHtml { inscriptions: vec![inscription_id(1), inscription_id(2)], } .to_string() .unindent(), "<h1>Latest Inscriptions</h1> <div class=thumbnails> <a href=/inscription/1{64}i1><iframe .* src=/preview/1{64}i1></iframe></a> <a href=/inscription/2{64}i2><iframe .* src=/preview/2{64}i2></iframe></a> </div> " .unindent(), ); } } #44,985,355text self.outputs[0].1 ); } } } Ok(self) } fn add_value(mut self) -> Result<Self> { let estimated_fee = self.estimate_fee(); let min_value = match self.target { Target::Postage => self.outputs.last().unwrap().0.script_pubkey().dust_value(), Target::Value(value) | Target::ExactPostage(value) => value, }; let total = min_value .checked_add(estimated_fee) .ok_or(Error::ValueOverflow)?; if let Some(mut deficit) = total.checked_sub(self.outputs.last().unwrap().1) { while deficit > Amount::ZERO { let additional_fee = self.fee_rate.fee(Self::ADDITIONAL_INPUT_VBYTES); let needed = deficit .checked_add(additional_fee) .ok_or(Error::ValueOverflow)?; let (utxo, value) = self.select_cardinal_utxo(needed, false)?; let benefit = value .checked_sub(additional_fee) .ok_or(Error::NotEnoughCardinalUtxos)?; self.inputs.push(utxo); self.outputs.last_mut().unwrap().1 += value; #44,985,354text Some(page_index - 1) } else { None }, next_page: if (page_index + 1) * 100 <= num_inscriptions { Some(page_index + 1) } else { None }, }) } } impl PageContent for InscriptionsBlockHtml { fn title(&self) -> String { format!("Inscriptions in Block {0}", self.block) } } #[cfg(test)] mod tests { use super::*; #[test] fn without_prev_and_next() { assert_regex_match!( InscriptionsBlockHtml { block: 21, inscriptions: vec![inscription_id(1), inscription_id(2)], prev_block: None, next_block: None, prev_page: None, next_page: None, }, " <h1>Inscriptions in <a href=/block/21>Block 21</a></h1> <div class=thumbnails> <a href=/inscription/1{64}i1><iframe .* src=/preview/1{64}i1></iframe></a> <a href=/inscription/2{64}i2><iframe .* src=/preview/2{64}i2></iframe></a> </div> .* prev next .* " #44,985,353textuse super::*; pub(crate) struct Iframe { inscription_id: InscriptionId, thumbnail: bool, } impl Iframe { pub(crate) fn thumbnail(inscription_id: InscriptionId) -> Trusted<Self> { Trusted(Self { inscription_id, thumbnail: true, }) } pub(crate) fn main(inscription_id: InscriptionId) -> Trusted<Self> { Trusted(Self { inscription_id, thumbnail: false, }) } } impl Display for Iframe { fn fmt(&self, f: &mut Formatter) -> fmt::Result { if self.thumbnail { write!(f, "<a href=/inscription/{}>", self.inscription_id)?; } write!( f, "<iframe sandbox=allow-scripts scrolling=no loading=lazy src=/preview/{}></iframe>", self.inscription_id )?; if self.thumbnail { write!(f, "</a>",)? } Ok(()) } } #[cfg(test)] mod tests { use super::*; #[test] fn thumbnail() { assert_regex_match!( Iframe::thumbnail(inscription_id(1)) .0.to_string(), "<a href=/inscription/1{64}i1><iframe sandbox=allow-scripts scrolling=no loading=lazy src=/preview/1{64}i1></iframe></a>", #44,985,350textuse super::*; #[derive(Boilerplate)] pub(crate) struct InputHtml { pub(crate) path: (u32, usize, usize), pub(crate) input: TxIn, } impl PageContent for InputHtml { fn title(&self) -> String { format!("Input /{}/{}/{}", self.path.0, self.path.1, self.path.2) } } #[cfg(test)] mod tests { use { super::*, bitcoin::{blockdata::script, Witness}, }; #[test] fn input_html() { let mut witness = Witness::new(); witness.push([1]); pretty_assert_eq!( InputHtml { path: (1, 2, 3), input: TxIn { previous_output: "0000000000000000000000000000000000000000000000000000000000000000:0" .parse() .unwrap(), script_sig: ScriptBuf::builder().push_slice(b"foo").into_script(), sequence: Sequence::MAX, witness, } } .to_string(), " <h1>Input /1/2/3</h1> <dl> <dt>previous output</dt><dd class=monospace>0000000000000000000000000000000000000000000000000000000000000000:0</dd> #44,985,347text } #[test] fn final_subsidy_height() { pretty_assert_eq!( ClockSvg::new(Height(6929999)).second, 1007.0 / 2016.0 * 360.0 ); pretty_assert_eq!( ClockSvg::new(Height(6929999)).minute, 209_999.0 / 210_000.0 * 360.0 ); pretty_assert_eq!( ClockSvg::new(Height(6929999)).hour, 6929999.0 / 6930000.0 * 360.0 ); } #[test] fn first_post_subsidy_height() { pretty_assert_eq!(ClockSvg::new(Height(6930000)).second, 180.0); pretty_assert_eq!(ClockSvg::new(Height(6930000)).minute, 0.0); pretty_assert_eq!(ClockSvg::new(Height(6930000)).hour, 0.0); } #[test] fn clock_svg() { assert_regex_match!( ClockSvg::new(Height(6929999)).to_string(), r##"<\?xml version="1.0" encoding="UTF-8"\?> <svg.*>.* <text.*>6929999</text>.* <line y2="-9" transform="rotate\(359.9999480519481\)"><title>Subsidy</title></line>.* <line y2="-13" stroke-width="0.6" transform="rotate\(359.9982857142857\)"><title>Epoch</title></line>.* <line y2="-16" stroke="#d00505" stroke-width="0.2" transform="rotate\(179.82142857142858\)"><title>Period</title></line>.* #44,985,346text assert_eq!(hash.len(), 40); "0x" .chars() .chain(address.chars().zip(hash.chars()).map(|(a, h)| match h { '0'..='7' => a, '8'..='9' | 'a'..='f' => a.to_ascii_uppercase(), _ => unreachable!(), })) .collect() } #[cfg(test)] mod tests { use super::*; #[test] fn test_eth_checksum_generation() { // test addresses from https://eips.ethereum.org/EIPS/eip-55 for addr in &[ "0x27b1fdb04752bbc536007a920d24acb045561c26", "0x52908400098527886E0F7030069857D2E4169EE7", "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", "0x8617E340B3D01FA5F11F306F4090FD50E238070D", "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", "0xde709f2102306220921060314715629080e2fb77", "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", ] { let lowercased = String::from(&addr[2..]).to_ascii_lowercase(); assert_eq!(addr.to_string(), create_address_with_checksum(&lowercased)); } } #[test] fn test_inscription_id_to_teleburn_address() { #44,985,345text inscription_id: *inscription_id, }); } } let amount = *self .amounts .get(&self.outgoing.outpoint) .ok_or(Error::NotInWallet(self.outgoing))?; if self.outgoing.offset >= amount.to_sat() { return Err(Error::OutOfRange(self.outgoing, amount.to_sat() - 1)); } self.utxos.remove(&self.outgoing.outpoint); self.inputs.push(self.outgoing.outpoint); self.outputs.push((self.recipient.clone(), amount)); tprintln!( "selected outgoing outpoint {} with value {}", self.outgoing.outpoint, amount.to_sat() ); Ok(self) } fn align_outgoing(mut self) -> Self { assert_eq!(self.outputs.len(), 1, "invariant: only one output"); assert_eq!( self.outputs[0].0, self.recipient, "invariant: first output is recipient" ); let sat_offset = self.calculate_sat_offset(); if sat_offset == 0 { tprintln!("outgoing is aligned"); } else { tprintln!("aligned outgoing with {sat_offset} sat padding output"); #44,985,344text