서론

이 핸드북은 오디널 이론(Ordinal Theory)에 대한 안내서다. 오디널 이론은 사토시(Satoshis)에 관한 것으로, 각 사토시에 개별적인 정체성을 부여함으로써 그것들을 추적과 전송할 수 있으며 그들에게 의미를 부여할 수 있다.

비트코인 네트워크의 원자적 자체 통화는 비트코인이 아닌 사토시다. 1 비트코인을 100,000,000 사토시로 분할할 수 있지만 그 이상은 불가능하다.

오디널 이론은 비트코인 외에 사이드체인이나 토큰을 필요로하지 않으며, 비트코인 네트워크를 변경하지 않고도 사용할 수 있다. 지금 바로 사용할 수 있다.

오디널 이론은 사토시에 화폐학적 가치를 부여하여 수집품처럼 모으고 거래할 수 있도록 해준다.

각 사토시에 임의의 콘텐츠를 새길 수 있으며, 이로써 비트코인 지갑에 보관하고 비트코인 거래를 통해 전송할 수 있는 고유한 비트코인 자체 디지털 아티팩트를 만들 수 있다. 인스크립션은 비트코인만큼이나 내구성이 있고, 불변하며, 안전하고, 탈중앙화되어 있다.

더 특이한 사용 사례도 가능하다: 오프체인 컬러드 코인, 키 로테이션이 가능한 공개 키 인프라, DNS에 탈중앙화된 대체. 하지만 현재로서는 이러한 사용 사례는 사색에 불과하며, 비주류 오디널 이론가들의 머릿속에만 존재한다.

오디널 이론에 대한 자세한 내용은 개요를 참조하자.

인스크립션에 대한 자세한 내용은 인스크립션을 참조하자.

When you're ready to get your hands dirty, a good place to start is with inscriptions, a curious species of digital artifact enabled by ordinal theory.

링크 모음

비디오 모음

오디널 이론 개요

오디널스는 개별 사토시(SAT)를 추적하고 전송할 수 있는 사토시를 위한 번호 체계이다. 이러한 번호를 서수라고 한다. 사토시는 채굴된 순서대로 번호가 매겨지며, 트랜잭션 입력에서 트랜잭션 출력으로 선입선출 방식으로 전송된다. 번호 체계와 전송 체계는 모두 순서 에 의존한다. 번호 체계는 사토시가 채굴되는 순서 에, 그리고 전송 체계는 트랜잭션 입력과 출력의 순서 에 의존한다. 따라서 오디널 이라는 이름이 붙었다.

기술적인 자세한 내용은 BIP에서 확인할 수 있다.

오디널 이론은 별도의 토큰이나 다른 블록체인 또는 비트코인에 어떠한 변경도 요구하지 않는다. 지금 바로 사용할 수 있다.

서수는 몇 가지 다른 방법으로 표현할 수 있다:

  • 정수 표기법 : 2099994106992659 사토시가 채굴된 순서에 따라 할당된 서수이다.

  • 소수 표기법 : 3891094.16797 첫 번째 숫자는 사토시가 채굴된 블록 높이(block height)이고, 두 번째 숫자는 블록 내 사토시의 오프셋(offset)이다.

  • 도 표기법 : 3°111094′214″16797‴. 잠시 후에 설명하겠다.

  • 백분의수 표기법 : 99.99971949060254% . 비트코인 공급량에서 사토시가 차지하는 위치를 백분율로 표시한다.

  • 이름 : satoshi. 문자 a부터 z까지를 사용하여 서수를 인코딩한다.

서수를 안정적 식별자로 사용해 NFT, 증권형 토큰, 계정, 스테이블코인 등 임의의 자산을 사토시에 첨부할 수 있다.

오디널스는 깃허브에서 개발된 오픈 소스 프로젝트다. 이 프로젝트는 오디널 체계를 설명하는 BIP, 비트코인 코어 노드와 통신하여 모든 사토시의 위치를 추적하는 인덱스, 오디널를 인식하고 트랜잭션를 할 수 있는 지갑, 블록체인의 대화형 탐색을 위한 블록 탐색기, 사토시에 디지털 아티팩트를 새기는 기능, 그리고 이 매뉴얼로 구성되었다.

Rarity

인간은 수집가이며, 이제 사토시를 추적하고 전송할 수 있기 때문에 사람들은 당연히 사토시를 수집하고 싶어 할 것이다. 어떤 SAT가 희귀하고 바람직한지는 각 오디널 이론가가 스스로 결정할 수 있지만, 몇 가지 힌트가 있다…

비트코인에는 주기적인 이벤트가 있으며, 일부는 빈번하고 일부는 드물게 발생하며, 이들은 자연스럽게 희귀성 시스템에 적합하다. 이러한 주기적 이벤트는 다음과 같다:

  • 블록 : 지금부터 영원히 약 10분마다 새로운 블록이 채굴된다.

  • 난이도 조정 : 비트코인 네트워크는 2016블록마다, 즉 약 2주마다 블록이 승인되기 위해 충족해야 하는 난이도 목표를 조정하여 해시레이트의 변화에 대응한다.

  • 반감기 : 210,000 블록마다, 즉 약 4년마다 모든 블록에서 생성되는 새로운 SAT의 양이 절반으로 줄어든다.

  • 사이클 : 6번의 반감기마다 마법 같은 일이 일어난다. 바로 반감기와 난이도 조정이 동시에 일어난다. 이를 합(conjunction)이라고 하며, 두 합 사이의 기간을 사이클이라고 한다. 합은 대략 24년마다 발생한다. 첫 번째 합은 2032년에 일어날 예정이다.

이에 따라 다음과 같은 희귀도 레벨이 정해진다:

  • common: 해당 블록의 첫 번째 SAT가 아닌 모든 SAT
  • uncommon: 각 블록의 첫 번째 SAT
  • rare: 각 난이도 조정 기간의 첫 번째 SAT
  • epic: 각 반감기의 첫 번째 SAT
  • legendary: 각 사이클의 첫 번째 SAT
  • mythic: 제네시스블록의 첫 번째 SAT

다음은 사토시의 희귀성을 한눈에 쉽게 알아볼 수 있도록 서수를 명확하게 표현하는 도 표기법을 알아보자:

A°B′C″D‴
│ │ │ ╰─ Index of sat in the block
│ │ ╰─── Index of block in difficulty adjustment period
│ ╰───── Index of block in halving epoch
╰─────── Cycle, numbered starting from 0

오디널 이론가들은 A, B, C, D 에 대해 각각 "시", "분", "초", 그리고 “third”라는 용어를 자주 사용한다.

이제 몇 가지 예를 보자. 이 사토시는 common등급이다:

1°1′1″1‴
│ │ │ ╰─ Not first sat in block
│ │ ╰─── Not first block in difficulty adjustment period
│ ╰───── Not first block in halving epoch
╰─────── Second cycle

이 사토시는 uncommon등급이다:

1°1′1″0‴
│ │ │ ╰─ First sat in block
│ │ ╰─── Not first block in difficulty adjustment period
│ ╰───── Not first block in halving epoch
╰─────── Second cycle

이 사토시는 rare등급이다:

1°1′0″0‴
│ │ │ ╰─ First sat in block
│ │ ╰─── First block in difficulty adjustment period
│ ╰───── Not the first block in halving epoch
╰─────── Second cycle

이 사토시는 epic등급이다:

1°0′1″0‴
│ │ │ ╰─ First sat in block
│ │ ╰─── Not first block in difficulty adjustment period
│ ╰───── First block in halving epoch
╰─────── Second cycle

이 사토시는 legendary등급이다:

1°0′0″0‴
│ │ │ ╰─ First sat in block
│ │ ╰─── First block in difficulty adjustment period
│ ╰───── First block in halving epoch
╰─────── Second cycle

그리고 이 사토시는 mythic등급이다:

0°0′0″0‴
│ │ │ ╰─ First sat in block
│ │ ╰─── First block in difficulty adjustment period
│ ╰───── First block in halving epoch
╰─────── First cycle

블록 오프셋이 0이면 생략할 수 있다. 이 것은 위에서 본 uncommon등급 사토시이다:

1°1′1″
│ │ ╰─ Not first block in difficulty adjustment period
│ ╰─── Not first block in halving epoch
╰───── Second cycle

희귀 사토시 공급

총 공급량

  • common: 2.1조
  • uncommon: 6,929,999
  • rare: 3437
  • epic: 32
  • legendary: 5
  • mythic: 1

현재 공급량

  • common: 1.9조
  • uncommon: 808,262
  • rare: 369
  • epic: 3
  • legendary: 0
  • mythic: 1

현재로서는 uncommon 사토시도 매우 드물다. 이 글을 쓰는 현재, 745,855개의 uncommon 사토시가 채굴되었다 - 유통되는 25.6비트코인당 1개.

이름

각 사토시는 A 부터 Z 까지의 문자로 구성된 이름이 있으며, 더 미래에서 채굴 될수록 사토시에 이름은 짧아진다. 짧게 시작해서 점점 길어질 수도 있지만, 그러면 좋고 짧은 이름들은 모두 소비가 불가능한 제네시스 블록에 갇히게 될 것이다.

예를 들어 1905530482684727°의 이름은 "iaiufjszmoba”이다. 마지막으로 채굴될 사토시의 이름은 “a”이다. 10자 이하의 모든 조합은 이미 존재하거나 언젠가는 존재할 것이다.

엑소틱

사토시는 이름이나 희귀성 이외의 이유로 소중히 여겨질 수 있다. 정수 제곱근이나 세제곱근과 같은 숫자 자체의 특성 때문일 수도 있다. 또는 세그윗이 활성화된 블록인 477,120 블록의 사토시나 마지막으로 채굴될 사토시인 2099999997689999°와 같은 역사적 사건과의 연관성 때문일 수도 있다.

이러한 사토시를 “엑소틱”(이색품)이라고 한다. 어떤 사토시가 엑소틱인지, 그리고 무엇 때문에 엑소틱인지는 주관적이다. 오디널 이론가들은 자신이 고안한 기준에 따라 엑소틱을 찾도록 권장한다.

인스크립션

사토시에 임의의 콘텐츠를 새겨 비트코인 고유의 디지털 아티팩트를 생성할 수 있다. 새김(inscribing)은 새김할 사토시를 해당 인스크립션 콘텐츠를 온체인에 공개해주는 트랜잭션안에 전송하는 방식으로 이루어진다. 이로써 이 콘텐츠는 해당 사토시와 불가분으로 연결되며, 추적, 전송, 비축, 구매, 판매, 분실, 재발견이 가능한 불변의 디지털 아티팩트로 전환된다.

고고학

초기 NFT를 목록화하고 수집하는 데 전념하는 고고학자들의 활발한 커뮤니티가 생겨났다. 여기에 역사적 NFT에 대한 Chainleft의 훌륭한 요약을 확인할 수 있다.

일반적으로 인정되는 초기 NFT에 마감일은 2018년 3월 19일로, 이더리움에 첫 번째 ERC-721 컨트랙트인 SU SQUARES가 배포된 날이다.

오디널스가 NFT 고고학자들의 관심을 끌지 여부는 아직 미지수다! 어떤 의미에서 오디널스는 오디널스 사양이 확정된 2022년 초에 만들어졌다. 이런한 점에서, 오디널스는 역사적으로 흥미롭지 않다.

하지만 다른 의미에서 오디널스는 사실 2009년 사토시 나카모토가 비트코인 제네시스 블록을 채굴할 때 만들어졌다. 이런 관점에서 오디널스, 특히 초기 오디널스는 분명 역사적으로 흥미로운 존재다.

많은 오디널 이론가들은 후자의 견해를 선호한다. 이는 특히 오디널스가 현대적 NFT 시대가 시작되기 훨씬 전에 적어도 두 차례에 걸쳐 독립적으로 발견되었기 때문이다.

2012년 8월 21일, 찰리 리는 비트코인 토크 포럼에 비트코인에 지분증명을 추가하자는 제안을 게시했다. 이는 자산 체계는 아니었지만 오디널 알고리즘을 사용했으며, 시행은 되었지만 배포되지는 않았다.

2012년 10월 8일, jl2012는 같은 포럼에 소수 표기법을 사용하고 오디널의 모든 중요한 속성을 가진 계획을 게시했다. 이 계획은 논의되었지만 시행되지 않았다.

이러한 오디널의 독립적인 발명은 어떻게 보면 오디널이 발명된 것이 아니라 발견되었거나 재발견되었음을 나타낸다. 오디널은 비트코인의 수학의 필연적인 결과로, 현대의 기록이 아니라 고대의 기원에서 비롯된 것이다. 오디널은 수년 전 첫 번째 블록의 채굴과 함께 시작된 일련의 사건의 정점이다.

디지털 아티팩트

물리적 인공물을 상상해 보라. 예를 들어, 밝혀지지 않은 세월 동안 어둡고 은밀한 바이킹 창고의 손아귀에 있던 희귀한 동전이 이제 여러분의 손으로 의해 땅속에서 파헤쳐졌다. 이 동전은…

...주인이 있다. 바로 당신. 당신이 안전하게 보관하는 한 누구도 빼앗을 수 없다.

...완전하다. 결여된 요소가 없다.

...당신에 의해서만 변화될 수 있다. 만약 당신이 상인이고 18세기 중국으로 갔었다면, 그 동전에 각인(chop-mark)을 찍을 수 있는 사람은 당신밖에 없었을 것이다.

...당신에 의해서만 처분될 수 있다. 당신이 원하는 누구에게나 판매, 거래 또는 선물 할 수 있다.

디지털 아티팩트(인공물)란 무엇인가? 간단히 말해, 이는 물리적 인공물의 디지털 버전이다.

디지털 한 것이 디지털 아티팩트가 되려면 당신의 그 동전과 같은 것이어야 한다:

  • 디지털 아티팩트는 소유자가 있을 수 있다. 숫자는 누구도 소유할 수 없으므로 디지털 아티팩트가 아니다.

  • 디지털 아티팩트는 완전하다. IPFS 또는 Arweave의 오프체인 콘텐츠를 가리키는 NFT는 불완전하며, 따라서 디지털 아티팩트가 아니다.

  • 디지털 아티팩트는 무허가성이라는 특성을 가지고 있다. 로열티를 지불하지 않고는 판매할 수 없는 NFT는 무허가성을 지니지 않으며, 따라서 디지털 아티팩트가 아니다.

  • 디지털 아티팩트는 검열할 수 없다. 중앙 원장의 데이터베이스 항목을 오늘은 변경할 수 있어도 내일은 변경할 수 없을 수도 있으므로 이는 디지털 아티팩트가 될 수 없다.

  • 디지털 아티팩트는 불변한다. 업그레이드 키가 있는 NFT는 디지털 아티팩트가 아니다.

디지털 아티팩트의 정의는 NFT가 추구해야하는, 그리고 간혹 부합하는, 그리고 인스크립션이 본질적으로 항상 부합하는 이상을 반영하기 위한 것이다.

인스크립션

인스크립션(새김)은 임의의 콘텐츠를 SAT에 새겨 넣어 비트코인 고유의 디지털 아티팩트(일반적인 명칭은 NFT)를 생성한다. 인스크립션은 사이드체인이나 별도의 토큰을 필요로 하지 않는다.

이렇게 새겨진 SAT는 비트코인 트랜잭션을 사용해 전송하고, 비트코인 주소로 보내고, 비트코인 UTXO에 보관할 수 있다. 이러한 트랜잭션, 주소, UTXO는 모든 면에서 일반적인 비트코인 트랜잭션, 주소, UTXOs와 동일다. 다만 개별 사토시를 전송하기 위해서는 트랜잭션이 오디널 이론에 따라 입력과 출력의 순서와 값을 제어해야 한다.

인스크립션 콘텐츠 모델은 웹의 콘텐츠 모델이다. 인스크립션은 MIME 유형이라고도 하는 콘텐츠 유형과 바이트 문자열(string)인 콘텐츠 자체로 구성된다. 이를 통해 웹 서버에서 인스크립션 콘텐츠를 반환하고 다른 인스크립션의 콘텐츠를 사용 및 리믹스하는 HTML 인스크립션을 만들 수 있다.

인스크립션 콘텐츠는 전적으로 온체인에 저장되며, 탭루트 스크립트 경로 지출 스크립트에 저장된다. 탭루트 스크립트는 콘텐츠에 대한 제한이 거의 없으며, 추가로 증인 할인(witness discount)을 받을 수 있어 인스크립션 콘텐츠 저장 비용이 상대적으로 저렴하다.

탭루트 스크립트 지출은 기존 탭루트 출력에서만 만들 수 있으므로, 인스크립션은 2단계 커밋/리빌 절차를 사용하여 만들어진다. 먼저 커밋 트랜잭션에서 인스크립션 내용이 포함된 스크립트에 커밋하는 탭루트 출력이 생성된다. 둘째, 리빌 트랜잭션에서는 커밋 트랜잭션에서 생성된 출력이 소비되어 인스크립션 콘텐츠를 온체인에 공개한다.

인스크립션 콘텐츠는 “엔벨롭”(envelope)이라고 하는 실행되지 않은 조건문 내의 데이터 푸시를 사용하여 직렬화된다. 엔벨롭는 데이터 푸시를 원하는 수만큼 감싸는 OP_FALSE OP_IF ... OP_ENDIF로 구성된다. 엔벨롭는 사실상 노옵(no-op)이므로 엔벨롭이 포함된 스크립트의 의미를 변경하지 않으며 다른 로킹(locking) 스크립트와 결합할 수 있다.

“Hello, world!”이라는 문자열이 포함된 텍스트 인스크립션은 다음과 같이 직렬화된다:

OP_FALSE
OP_IF
  OP_PUSH “ord”
  OP_PUSH 1
  OP_PUSH “text/plain;charset=utf-8”
  OP_PUSH 0
  OP_PUSH “Hello, world!”
OP_ENDIF

먼저 ord 문자열이 푸시되어 인스크립션을 엔벨롭의 다른 용도와 구분할 수 있다.

OP_PUSH 1은 다음 푸시에 콘텐츠 유형이 포함되어 있음을 나타내고, OP_PUSH 0은 후속 데이터 푸시에 콘텐츠 자체가 포함되어 있음을 나타낸다. 탭루트의 몇 가지 제한 사항 중 하나는 개별 데이터 푸시가 520바이트를 초과할 수 없다는 것이므로, 큰 인스크립션에는 여러 개의 데이터 푸시를 사용해야 한다.

The inscription content is contained within the input of a reveal transaction, and the inscription is made on the first sat of its input if it has no pointer field. This sat can then be tracked using the familiar rules of ordinal theory, allowing it to be transferred, bought, sold, lost to fees, and recovered.

콘텐츠

인스크립션의 데이터 모델은 웹 서버에서 인스크립션 콘텐츠를 제공하고 웹 브라우저에서 볼 수 있도록 하는 HTTP 응답의 데이터 모델이다.

필드

인스크립션은 optional body 앞에 필드를 포함할 수 있다. 각 필드는 두 개의 데이터 푸시, 즉 태그 및 값으로 구성된다.

Currently, there are six defined fields:

  • content_type, with a tag of 1, whose value is the MIME type of the body.
  • pointer, with a tag of 2, see pointer docs.
  • parent, with a tag of 3, see provenance.
  • metadata, with a tag of 5, see metadata.
  • metaprotocol, with a tag of 7, whose value is the metaprotocol identifier.
  • content_encoding, with a tag of 9, whose value is the encoding of the body.
  • delegate, with a tag of 11, see delegate.

Body의 시작과 필드의 끝은 빈 데이터 푸시로 표시된다.

인식되지 않는 태그는 라이트닝 네트워크에서 사용하는 "홀수여도 괜찮아" 규칙에 따라 짝수인지 홀수인지에 따라 다르게 해석된다.

인스크립션 생성, 초기 할당 또는 전송에 영향을 줄 수 있는 필드에는 짝수 태그가 사용된다. 따라서 인식할 수 없는 짝수 필드가 있는 인스크립션은 “unbound”, 즉 위치가 없는 상태로 표시되어야 한다.

홀수 태그는 추가 메타데이터와 같이 생성, 초기 할당 또는 전송에 영향을 주지 않는 필드에 사용되므로 무시해도 안전하다.

인스크립션 ID

인스크립션은 리빌 트랜잭션의 입력값에 포함되어 있다. 인스크립션을 고유하게 식별하기 위해 인스크립션에는 이 형식의 ID가 할당된다:

521f8eccffa4c41a3a7728dd012ea5a4a02feed81f41159231251ecf1e5c79dai0

i 앞 부분은 리빌 트랜잭션의 트랜잭션 ID(txid)이다. i 뒤의 숫자는 리빌 트랜잭션에 새겨지는 새 인스크립션의 인덱스(0부터 시작)를 정의한다.

인스크립션은 다른 입력 아니면 동일한 입력 내에 위치하거나 둘 다 일수 있다. 어떤 경우든 구문 분석기는 입력을 연속적으로 살펴보고 모든 인스크립션 ‘엔벨롭’을 찾기 때문에 순서는 명확하다.

입력인스크립션 개수인덱스
02i0, i1
11i2
23i3, i4, i5
30
41i6

Inscription Numbers

Inscriptions are assigned inscription numbers starting at zero, first by the order reveal transactions appear in blocks, and the order that reveal envelopes appear in those transactions.

Due to a historical bug in ord which cannot be fixed without changing a great many inscription numbers, inscriptions which are revealed and then immediately spent to fees are numbered as if they appear last in the block in which they are revealed.

Inscriptions which are cursed are numbered starting at negative one, counting down. Cursed inscriptions on and after the jubilee at block 824544 are vindicated, and are assigned positive inscription numbers.

샌드박싱 (sandboxing)

오프체인 콘텐츠에 대한 참조를 방지하기 위해 HTML 및 SVG 인스크립션은 샌드박스가 적용되어 인스크립션의 변경을 불가능하게 하고 독립적으로 유지될 수 있게 한다.

이는 HTML 및 SVG 인스크립션을 ‘sandbox’ 속성을 사용하여 'iframe' 내에 로드하고 Content-Security-Policy 헤더를 사용하여 인스크립션 콘텐츠를 제공함으로써 수행된다.

Self-Reference

The content of the inscription with ID INSCRIPTION_ID must served from the URL path /content/<INSCRIPTION_ID>.

This allows inscriptions to retrieve their own inscription ID with:

let inscription_id = window.location.pathname.split("/").pop();

If an inscription with ID X delegates to an inscription with ID Y, that is to say, if inscription X contains a delegate field with value Y, the content of inscription X must be served from the URL path /content/X, not /content/Y.

This allows delegating inscriptions to use their own inscription ID as a seed for generative delegate content.

Reinscriptions

Previously inscribed sats can be reinscribed with the --reinscribe command if the inscription is present in the wallet. This will only append an inscription to a sat, not change the initial inscription.

Reinscribe with satpoint: ord wallet inscribe --fee-rate <FEE_RATE> --reinscribe --file <FILE> --satpoint <SATPOINT>

Reinscribe on a sat (requires sat index): ord --index-sats wallet inscribe --fee-rate <FEE_RATE> --reinscribe --file <FILE> --sat <SAT>

Delegate

Inscriptions may nominate a delegate inscription. Requests for the content of an inscription with a delegate will instead return the content, content type and content encoding of the delegate. This can be used to cheaply create copies of an inscription.

설명서

To create an inscription I with delegate inscription D:

  • Create an inscription D. Note that inscription D does not have to exist when making inscription I. It may be inscribed later. Before inscription D is inscribed, requests for the content of inscription I will return a 404.
  • Include tag 11, i.e. OP_PUSH 11, in I, with the value of the serialized binary inscription ID of D, serialized as the 32-byte TXID, followed by the four-byte little-endian INDEX, with trailing zeroes omitted.

NB 비트코인 트랜잭션 ID의 바이트는 텍스트 표현이 역순으로되어 있으므로 직렬화된 트랜잭션 ID는 반대 순서가 된다.

예제

An example of an inscription which delegates to 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fi0:

OP_FALSE
OP_IF
  OP_PUSH "ord"
  OP_PUSH 11
  OP_PUSH 0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100
OP_ENDIF

Note that the value of tag 11 is decimal, not hex.

The delegate field value uses the same encoding as the parent field. See provenance for more examples of inscription ID encodings;

메타 데이터

Inscriptions may include CBOR metadata, stored as data pushes in fields with tag 5. Since data pushes are limited to 520 bytes, metadata longer than 520 bytes must be split into multiple tag 5 fields, which will then be concatenated before decoding.

Metadata is human readable, and all metadata will be displayed to the user with its inscription. Inscribers are encouraged to consider how metadata will be displayed, and make metadata concise and attractive.

Metadata is rendered to HTML for display as follows:

  • null, true, false, numbers, floats, and strings are rendered as plain text.
  • Byte strings are rendered as uppercase hexadecimal.
  • Arrays are rendered as <ul> tags, with every element wrapped in <li> tags.
  • Maps are rendered as <dl> tags, with every key wrapped in <dt> tags, and every value wrapped in <dd> tags.
  • Tags are rendered as the tag , enclosed in a <sup> tag, followed by the value.

CBOR is a complex spec with many different data types, and multiple ways of representing the same data. Exotic data types, such as tags, floats, and bignums, and encoding such as indefinite values, may fail to display correctly or at all. Contributions to ord to remedy this are welcome.

예제

Since CBOR is not human readable, in these examples it is represented as JSON. Keep in mind that this is only for these examples, and JSON metadata will not be displayed correctly.

The metadata {"foo":"bar","baz":[null,true,false,0]} would be included in an inscription as:

OP_FALSE
OP_IF
    ...
    OP_PUSH 0x05 OP_PUSH '{"foo":"bar","baz":[null,true,false,0]}'
    ...
OP_ENDIF

And rendered as:

<dl>
  ...
  <dt>metadata</dt>
  <dd>
    <dl>
      <dt>foo</dt>
      <dd>bar</dd>
      <dt>baz</dt>
      <dd>
        <ul>
          <li>null</li>
          <li>true</li>
          <li>false</li>
          <li>0</li>
        </ul>
      </dd>
    </dl>
  </dd>
  ...
</dl>

Metadata longer than 520 bytes must be split into multiple fields:

OP_FALSE
OP_IF
    ...
    OP_PUSH 0x05 OP_PUSH '{"very":"long","metadata":'
    OP_PUSH 0x05 OP_PUSH '"is","finally":"done"}'
    ...
OP_ENDIF

Which would then be concatenated into {"very":"long","metadata":"is","finally":"done"}.

Pointer

In order to make an inscription on a sat other than the first of its input, a zero-based integer, called the "pointer", can be provided with tag 2, causing the inscription to be made on the sat at the given position in the outputs. If the pointer is equal to or greater than the number of total sats in the outputs of the inscribe transaction, it is ignored, and the inscription is made as usual. The value of the pointer field is a little endian integer, with trailing zeroes ignored.

An even tag is used, so that old versions of ord consider the inscription to be unbound, instead of assigning it, incorrectly, to the first sat.

This can be used to create multiple inscriptions in a single transaction on different sats, when otherwise they would be made on the same sat.

Examples

An inscription with pointer 255:

OP_FALSE
OP_IF
  OP_PUSH "ord"
  OP_PUSH 1
  OP_PUSH "text/plain;charset=utf-8"
  OP_PUSH 2
  OP_PUSH 0xff
  OP_PUSH 0
  OP_PUSH "Hello, world!"
OP_ENDIF

An inscription with pointer 256:

OP_FALSE
OP_IF
  OP_PUSH "ord"
  OP_PUSH 1
  OP_PUSH "text/plain;charset=utf-8"
  OP_PUSH 2
  OP_PUSH 0x0001
  OP_PUSH 0
  OP_PUSH "Hello, world!"
OP_ENDIF

An inscription with pointer 256, with trailing zeroes, which are ignored:

OP_FALSE
OP_IF
  OP_PUSH "ord"
  OP_PUSH 1
  OP_PUSH "text/plain;charset=utf-8"
  OP_PUSH 2
  OP_PUSH 0x000100
  OP_PUSH 0
  OP_PUSH "Hello, world!"
OP_ENDIF

기원

인스크립션 소유자는 자식 인스크립션을 생성할 수 있으며, 해당 자식의 출처를 부모 인스크립션 소유자가 생성한 것으로 온체인에서 신뢰 없이 입증할 수 있다. 이는 부모 인스크립션의 자식이 동일한 컬렉션의 멤버가 되는 컬렉션에 사용할 수 있다.

자식이 자식을 가질 수 있으므로 복잡한 계층 구조가 가능하다. 예를 들어, 아티스트가 자신을 나타내는 인스크립션을 만들고 하위 인스크립션은 자신이 만든 컬렉션을 나타내며, 이 하위 인스크립션의 자식은 해당 컬렉션의 아이템이 될 수 있다.

설명서

부모 인스크립션 P로 자식 인스크립션 C를 생성하려면:

  • C에 대해 평소와 같이 인스크립션 트랜잭션 T를 생성한다.
  • 부모 P를 T의 입력 중 하나에 쓴다.
  • C에 태그 '3', 즉 'OP_PUSH 3'을 포함하고, 32바이트 'TXID'로 직렬화된 P의 바이너리(이진수) 인스크립션 ID 값과 뒤에오는 0들을 생략한 4바이트 리틀엔디안 'INDEX'를 포함시킨다.

NB 비트코인 트랜잭션 ID의 바이트는 텍스트 표현이 역순으로되어 있으므로 직렬화된 트랜잭션 ID는 반대 순서가 된다.

예제

000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fi0의 자식 인스크립션의 예시:

OP_FALSE
OP_IF
  OP_PUSH “ord”
  OP_PUSH 1
  OP_PUSH “text/plain;charset=utf-8”
  OP_PUSH 3
  OP_PUSH 0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100
  OP_PUSH 0
  OP_PUSH “Hello, world!”
OP_ENDIF

태그 3의 값은 헥스(16진수)가 아닌 바이너리(이진수)이며, 자식 비문이 자식으로 인식되려면 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fi0가 인스크립션 트랜잭션의 입력 중 하나로 소비되어야 한다.

인스크립션 ID 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fi255의 인코딩 예시:

OP_FALSE
OP_IF
  …
  OP_PUSH 3
  OP_PUSH 0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100ff
  …
OP_ENDIF

그리고 인스크립션 ID 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fi256의 경우:

OP_FALSE
OP_IF
  …
  OP_PUSH 3
  OP_PUSH 0x1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201000001
  …
OP_ENDIF

메모

태그 3은 사용 가능한 첫 번째 홀수 태그이기 때문에 사용된다. 인식되지 않는 홀수 태그는 인스크립션을 unbound(바인딩 해제)하지 않으므로 하위 인스크립션은 이전 버전의 ord에서 인식 및 추적된다.

컬렉션의 상위 인스크립션을 소각하여 컬렉션을 폐쇄할 수 있으며, 이 경우 컬렉션의 아이템을 더 이상 발행할 수 없게 된다.

리커젼

An important exception to sandboxing is recursion. Recursive endpoints are whitelisted endpoints that allow access to on-chain data, including the content of other inscriptions.

Since changes to recursive endpoints might break inscriptions that rely on them, recursive endpoints have backwards-compatibility guarantees not shared by ord server's other endpoints. In particular:

  • Recursive endpoints will not be removed
  • Object fields returned by recursive endpoints will not be renamed or change types

However, additional object fields may be added or reordered, so inscriptions must handle additional, unexpected fields, and must not expect fields to be returned in a specific order.

Recursion has a number of interesting use-cases:

  • 기존 인스크립션의 콘텐츠를 리믹스.

  • 코드, 이미지, 오디오 또는 스타일시트 스니펫을 공유된 공개 리소스로 발행.

  • 알고리즘이 자바스크립트로 새겨져 있고 고유한 시드를 가진 여러 인스크립션에서 인스턴스화되는 제너레이티브 아트 컬렉션.

  • 액세서리와 속성을 개별 이미지 또는 공유된 텍스처 아틀라스(texture atlas) 안에 인스크립션으로 새긴 다음 콜라주 스타일로 여러 인스크립션에서 고유한 조합으로 결합하는 제네레이티브 프로필 사진 컬렉션.

The recursive endpoints are:

  • /content/<INSCRIPTION_ID>: the content of the inscription with <INSCRIPTION_ID>
  • /r/blockhash/<HEIGHT>: block hash at given block height.
  • /r/blockhash: latest block hash.
  • /r/blockheight: latest block height.
  • /r/blockinfo/<QUERY>: block info. <QUERY> may be a block height or block hash.
  • /r/blocktime: UNIX time stamp of latest block.
  • /r/children/<INSCRIPTION_ID>: the first 100 child inscription ids.
  • /r/children/<INSCRIPTION_ID>/<PAGE>: the set of 100 child inscription ids on <PAGE>.
  • /r/inscription/<INSCRIPTION_ID>: information about an inscription
  • /r/metadata/<INSCRIPTION_ID>: JSON string containing the hex-encoded CBOR metadata.
  • /r/sat/<SAT_NUMBER>: the first 100 inscription ids on a sat.
  • /r/sat/<SAT_NUMBER>/<PAGE>: the set of 100 inscription ids on <PAGE>.
  • /r/sat/<SAT_NUMBER>/at/<INDEX>: the inscription id at <INDEX> of all inscriptions on a sat. <INDEX> may be a negative number to index from the back. 0 being the first and -1 being the most recent for example.

Note: <SAT_NUMBER> only allows the actual number of a sat no other sat notations like degree, percentile or decimal. We may expand to allow those in the future.

Responses from the above recursive endpoints are JSON. For backwards compatibility additional endpoints are supported, some of which return plain-text responses.

  • /blockheight: 최신 블록 높이.
  • /blockhash: 최신 블록 해시.
  • /blockhash/<HEIGHT>: 주어진 블록 높이에 블록 해시.
  • /blocktime: 최신 블록의 UNIX 타임스탬프.

Examples

  • /r/blockhash/0:
"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
  • /r/blockheight:
777000
  • /r/blockinfo/0:
{
  "average_fee": 0,
  "average_fee_rate": 0,
  "bits": 486604799,
  "chainwork": "0000000000000000000000000000000000000000000000000000000100010001",
  "confirmations": 0,
  "difficulty": 0.0,
  "hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
  "height": 0,
  "max_fee": 0,
  "max_fee_rate": 0,
  "max_tx_size": 0,
  "median_fee": 0,
  "median_time": 1231006505,
  "merkle_root": "0000000000000000000000000000000000000000000000000000000000000000",
  "min_fee": 0,
  "min_fee_rate": 0,
  "next_block": null,
  "nonce": 0,
  "previous_block": null,
  "subsidy": 5000000000,
  "target": "00000000ffff0000000000000000000000000000000000000000000000000000",
  "timestamp": 1231006505,
  "total_fee": 0,
  "total_size": 0,
  "total_weight": 0,
  "transaction_count": 1,
  "version": 1
}
  • /r/blocktime:
1700770905
  • /r/children/60bcf821240064a9c55225c4f01711b0ebbcab39aa3fafeefe4299ab158536fai0/49:
{
   "ids":[
      "7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4900",
      "7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4901",
      ...
      "7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4935",
      "7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4936"
   ],
   "more":false,
   "page":49
}
  • /r/inscription/3bd72a7ef68776c9429961e43043ff65efa7fb2d8bb407386a9e3b19f149bc36i0
{
  "charms": [],
  "content_type": "image/png",
  "content_length": 144037,
  "fee": 36352,
  "height": 209,
  "id": "3bd72a7ef68776c9429961e43043ff65efa7fb2d8bb407386a9e3b19f149bc36i0",
  "number": 2,
  "output": "3bd72a7ef68776c9429961e43043ff65efa7fb2d8bb407386a9e3b19f149bc36:0",
  "sat": null,
  "satpoint": "3bd72a7ef68776c9429961e43043ff65efa7fb2d8bb407386a9e3b19f149bc36:0:0",
  "timestamp": 1708312562,
  "value": 10000
}
  • /r/metadata/35b66389b44535861c44b2b18ed602997ee11db9a30d384ae89630c9fc6f011fi3:
"a2657469746c65664d656d6f727966617574686f726e79656c6c6f775f6f72645f626f74"
  • /r/sat/1023795949035695:
{
   "ids":[
      "17541f6adf6eb160d52bc6eb0a3546c7c1d2adfe607b1a3cddc72cc0619526adi0"
   ],
   "more":false,
   "page":0
}
  • /r/sat/1023795949035695/at/-1:
{
   "id":"17541f6adf6eb160d52bc6eb0a3546c7c1d2adfe607b1a3cddc72cc0619526adi0"
}
  • /r/children/60bcf821240064a9c55225c4f01711b0ebbcab39aa3fafeefe4299ab158536fai0/49:
{
   "ids":[
      "7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4900",
      "7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4901",
      ...
      "7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4935",
      "7cd66b8e3a63dcd2fada917119830286bca0637267709d6df1ca78d98a1b4487i4936"
   ],
   "more":false,
   "page":49
}

Rendering

Aspect Ratio

Inscriptions should be rendered with a square aspect ratio. Non-square aspect ratio inscriptions should not be cropped, and should instead be centered and resized to fit within their container.

Maximum Size

The ord explorer, used by ordinals.com, displays inscription previews with a maximum size of 576 by 576 pixels, making it a reasonable choice when choosing a maximum display size.

Image Rendering

The CSS image-rendering property controls how images are resampled when upscaled and downscaled.

When downscaling image inscriptions, image-rendering: auto, should be used. This is desirable even when downscaling pixel art.

When upscaling image inscriptions other than AVIF, image-rendering: pixelated should be used. This is desirable when upscaling pixel art, since it preserves the sharp edges of pixels. It is undesirable when upscaling non-pixel art, but should still be used for visual compatibility with the ord explorer.

When upscaling AVIF and JPEG XL inscriptions, image-rendering: auto should be used. This allows inscribers to opt-in to non-pixelated upscaling for non-pixel art inscriptions. Until such time as JPEG XL is widely supported by browsers, it is not a recommended image format.

Runes

Runes allow Bitcoin transactions to etch, mint, and transfer Bitcoin-native digital commodities.

Whereas every inscription is unique, every unit of a rune is the same. They are interchangeable tokens, fit for a variety of purposes.

Runestones

Rune protocol messages, called runestones, are stored in Bitcoin transaction outputs.

A runestone output's script pubkey begins with an OP_RETURN, followed by OP_13, followed by zero or more data pushes. These data pushes are concatenated and decoded into a sequence of 128-bit integers, and finally parsed into a runestone.

A transaction may have at most one runestone.

A runestone may etch a new rune, mint an existing rune, and transfer runes from a transaction's inputs to its outputs.

A transaction output may hold balances of any number of runes.

Runes are identified by IDs, which consist of the block in which a rune was etched and the index of the etching transaction within that block, represented in text as BLOCK:TX. For example, the ID of the rune etched in the 20th transaction of the 500th block is 500:20.

Etching

Runes come into existence by being etched. Etching creates a rune and sets its properties. Once set, these properties are immutable, even to its etcher.

Name

Names consist of the letters A through Z and are between one and twenty-six letters long. For example UNCOMMONGOODS is a rune name.

Names may contain spacers, represented as bullets, to aid readability. UNCOMMONGOODS might be etched as UNCOMMON•GOODS.

The uniqueness of a name does not depend on spacers. Thus, a rune may not be etched with the same sequence of letters as an existing rune, even if it has different spacers.

Spacers can only be placed between two letters. Finally, spacers do not count towards the letter count.

Divisibility

A rune's divisibility is how finely it may be divided into its atomic units. Divisibility is expressed as the number of digits permissible after the decimal point in an amount of runes. A rune with divisibility 0 may not be divided. A unit of a rune with divisibility 1 may be divided into ten sub-units, a rune with divisibility 2 may be divided into a hundred, and so on.

Symbol

A rune's currency symbol is a single Unicode code point, for example $, , or 🧿, displayed after quantities of that rune.

101 atomic units of a rune with divisibility 2 and symbol 🧿 would be rendered as 1.01 🧿.

If a rune does not have a symbol, the generic currency sign ¤, also called a scarab, should be used.

Premine

The etcher of a rune may optionally allocate to themselves units of the rune being etched. This allocation is called a premine.

Terms

A rune may have an open mint, allowing anyone to create and allocate units of that rune for themselves. An open mint is subject to terms, which are set upon etching.

A mint is open while all terms of the mint are satisfied, and closed when any of them are not. For example, a mint may be limited to a starting height, an ending height, and a cap, and will be open between the starting height and ending height, or until the cap is reached, whichever comes first.

Cap

The number of times a rune may be minted is its cap. A mint is closed once the cap is reached.

Amount

Each mint transaction creates a fixed amount of new units of a rune.

Start Height

A mint is open starting in the block with the given start height.

End Height

A rune may not be minted in or after the block with the given end height.

Start Offset

A mint is open starting in the block whose height is equal to the start offset plus the height of the block in which the rune was etched.

End Offset

A rune may not be minted in or after the block whose height is equal to the end offset plus the height of the block in which the rune was etched.

Minting

While a rune's mint is open, anyone may create a mint transaction that creates a fixed amount of new units of that rune, subject to the terms of the mint.

Transferring

When transaction inputs contain runes, or new runes are created by a premine or mint, those runes are transferred to that transaction's outputs. A transaction's runestone may change how input runes transfer to outputs.

Edicts

A runestone may contain any number of edicts. Edicts consist of a rune ID, an amount, and an output number. Edicts are processed in order, allocating unallocated runes to outputs.

Pointer

After all edicts are processed, remaining unallocated runes are transferred to the transaction's first non-OP_RETURN output. A runestone may optionally contain a pointer that specifies an alternative default output.

Burning

Runes may be burned by transferring them to an OP_RETURN output with an edict or pointer.

Cenotaphs

Runestones may be malformed for a number of reasons, including non-pushdata opcodes in the runestone OP_RETURN, invalid varints, or unrecognized runestone fields.

Malformed runestones are termed cenotaphs.

Runes input to a transaction with a cenotaph are burned. Runes etched in a transaction with a cenotaph are set as unmintable. Mints in a transaction with a cenotaph count towards the mint cap, but the minted runes are burned.

Cenotaphs are an upgrade mechanism, allowing runestones to be given new semantics that change how runes are created and transferred, while not misleading unupgraded clients as to the location of those runes, as unupgraded clients will see those runes as having been burned.

Runes Does Not Have a Specification

The Runes reference implementation, ord, is the normative specification of the Runes protocol.

Nothing you read here or elsewhere, aside from the code of ord, is a specification. This prose description of the runes protocol is provided as a guide to the behavior of ord, and the code of ord itself should always be consulted to confirm the correctness of any prose description.

If, due to a bug in ord, this document diverges from the actual behavior of ord and it is impractically disruptive to change ord's behavior, this document will be amended to agree with ord's actual behavior.

Users of alternative implementations do so at their own risk, and services wishing to integrate Runes are strongly encouraged to use ord itself to make Runes transactions, and to determine the state of runes, mints, and balances.

Runestones

Rune protocol messages are termed "runestones".

The Runes protocol activates on block 840,000. Runestones in earlier blocks are ignored.

Abstractly, runestones contain the following fields:

#![allow(unused)]
fn main() {
struct Runestone {
  edicts: Vec<Edict>,
  etching: Option<Etching>,
  mint: Option<RuneId>,
  pointer: Option<u32>,
}
}

Runes are created by etchings:

#![allow(unused)]
fn main() {
struct Etching {
  divisibility: Option<u8>,
  premine: Option<u128>,
  rune: Option<Rune>,
  spacers: Option<u32>,
  symbol: Option<char>,
  terms: Option<Terms>,
}
}

Which may contain mint terms:

#![allow(unused)]
fn main() {
struct Terms {
  amount: Option<u128>,
  cap: Option<u128>,
  height: (Option<u64>, Option<u64>),
  offset: (Option<u64>, Option<u64>),
}
}

Runes are transferred by edict:

#![allow(unused)]
fn main() {
struct Edict {
  id: RuneId,
  amount: u128,
  output: u32,
}
}

Rune IDs are encoded as the block height and transaction index of the transaction in which the rune was etched:

#![allow(unused)]
fn main() {
struct RuneId {
  block: u64,
  tx: u32,
}
}

Rune IDs are represented in text as BLOCK:TX.

Rune names are encoded as modified base-26 integers:

#![allow(unused)]
fn main() {
struct Rune(u128);
}

Deciphering

Runestones are deciphered from transactions with the following steps:

  1. Find the first transaction output whose script pubkey begins with OP_RETURN OP_13.

  2. Concatenate all following data pushes into a payload buffer.

  3. Decode a sequence 128-bit LEB128 integers from the payload buffer.

  4. Parse the sequence of integers into an untyped message.

  5. Parse the untyped message into a runestone.

Deciphering may produce a malformed runestone, termed a cenotaph.

Locating the Runestone Output

Outputs are searched for the first script pubkey that beings with OP_RETURN OP_13. If deciphering fails, later matching outputs are not considered.

Assembling the Payload Buffer

The payload buffer is assembled by concatenating data pushes, after OP_13, in the matching script pubkey.

Data pushes are opcodes 0 through 78 inclusive. If a non-data push opcode is encountered, i.e., any opcode equal to or greater than opcode 79, the deciphered runestone is a cenotaph with no etching, mint, or edicts.

Decoding the Integer Sequence

A sequence of 128-bit integers are decoded from the payload as LEB128 varints.

LEB128 varints are encoded as sequence of bytes, each of which has the most-significant bit set, except for the last.

If a LEB128 varint contains more than 18 bytes, would overflow a u128, or is truncated, meaning that the end of the payload buffer is reached before encountering a byte with the continuation bit not set, the decoded runestone is a cenotaph with no etching, mint, or edicts.

Parsing the Message

The integer sequence is parsed into an untyped message:

#![allow(unused)]
fn main() {
struct Message {
  fields: Map<u128, Vec<u128>>,
  edicts: Vec<Edict>,
}
}

The integers are interpreted as a sequence of tag/value pairs, with duplicate tags appending their value to the field value.

If a tag with value zero is encountered, all following integers are interpreted as a series of four-integer edicts, each consisting of a rune ID block height, rune ID transaction index, amount, and output.

#![allow(unused)]
fn main() {
struct Edict {
  id: RuneId,
  amount: u128,
  output: u32,
}
}

Rune ID block heights and transaction indices in edicts are delta encoded.

Edict rune ID decoding starts with a base block height and transaction index of zero. When decoding each rune ID, first the encoded block height delta is added to the base block height. If the block height delta is zero, the next integer is a transaction index delta. If the block height delta is greater than zero, the next integer is instead an absolute transaction index.

This implies that edicts must first be sorted by rune ID before being encoded in a runestone.

For example, to encode the following edicts:

blockTXamountoutput
10551
501254
10718
105103

They are first sorted by block height and transaction index:

blockTXamountoutput
10551
105103
10718
501254

And then delta encoded as:

block deltaTX deltaamountoutput
10551
00103
0218
401254

If an edict output is greater than the number of outputs of the transaction, an edict rune ID is encountered with block zero and nonzero transaction index, or a field is truncated, meaning a tag is encountered without a value, the decoded runestone is a cenotaph.

Note that if a cenotaph is produced here, the cenotaph is not empty, meaning that it contains the fields and edicts, which may include an etching and mint.

Parsing the Runestone

The runestone:

#![allow(unused)]
fn main() {
struct Runestone {
  edicts: Vec<Edict>,
  etching: Option<Etching>,
  mint: Option<RuneId>,
  pointer: Option<u32>,
}
}

Is parsed from the unsigned message using the following tags:

#![allow(unused)]
fn main() {
enum Tag {
  Body = 0,
  Flags = 2,
  Rune = 4,
  Premine = 6,
  Cap = 8,
  Amount = 10,
  HeightStart = 12,
  HeightEnd = 14,
  OffsetStart = 16,
  OffsetEnd = 18,
  Mint = 20,
  Pointer = 22,
  Cenotaph = 126,

  Divisibility = 1,
  Spacers = 3,
  Symbol = 5,
  Nop = 127,
}
}

Note that tags are grouped by parity, i.e., whether they are even or odd. Unrecognized odd tags are ignored. Unrecognized even tags produce a cenotaph.

All unused tags are reserved for use by the protocol, may be assigned at any time, and must not be used.

Body

The Body tag marks the end of the runestone's fields, causing all following integers to be interpreted as edicts.

Flags

The Flag field contains a bitmap of flags, whose position is 1 << FLAG_VALUE:

#![allow(unused)]
fn main() {
enum Flag {
  Etching = 0,
  Terms = 1,
  Turbo = 2,
  Cenotaph = 127,
}
}

The Etching flag marks this transaction as containing an etching.

The Terms flag marks this transaction's etching as having open mint terms.

The Turbo flag marks this transaction's etching as opting into future protocol changes. These protocol changes may increase light client validation costs, or just be highly degenerate.

The Cenotaph flag is unrecognized.

If the value of the flags field after removing recognized flags is nonzero, the runestone is a cenotaph.

Rune

The Rune field contains the name of the rune being etched. If the Etching flag is set but the Rune field is omitted, a reserved rune name is allocated.

Premine

The Premine field contains the amount of premined runes.

Cap

The Cap field contains the allowed number of mints.

Amount

The Amount field contains the amount of runes each mint transaction receives.

HeightStart and HeightEnd

The HeightStart and HeightEnd fields contain the mint's starting and ending absolute block heights, respectively. The mint is open starting in the block with height HeightStart, and closes in the block with height HeightEnd.

OffsetStart and OffsetEnd

The OffsetStart and OffsetEnd fields contain the mint's starting and ending block heights, relative to the block in which the etching is mined. The mint is open starting in the block with height OffsetStart + ETCHING_HEIGHT, and closes in the block with height OffsetEnd + ETCHING_HEIGHT.

Mint

The Mint field contains the Rune ID of the rune to be minted in this transaction.

Pointer

The Pointer field contains the index of the output to which runes unallocated by edicts should be transferred. If the Pointer field is absent, unallocated runes are transferred to the first non-OP_RETURN output.

Cenotaph

The Cenotaph field is unrecognized.

Divisibility

The Divisibility field, raised to the power of ten, is the number of subunits in a super unit of runes.

For example, the amount 1234 of different runes with divisibility 0 through 3 is displayed as follows:

DivisibilityDisplay
01234
1123.4
212.34
31.234
Spacers

The Spacers field is a bitfield of spacers that should be displayed between the letters of the rune's name.

The Nth field of the bitfield, starting from the least significant, determines whether or not a spacer should be displayed between the Nth and N+1th character, starting from the left of the rune's name.

For example, the rune name AAAA rendered with different spacers:

SpacersDisplay
0b1A•AAA
0b11A•A•AA
0b10AA•AA
0b111A•A•A•A

Trailing spacers are ignored.

Symbol

The Symbol field is the Unicode codepoint of the Rune's currency symbol, which should be displayed after amounts of that rune. If a rune does not have a currency symbol, the generic currency character ¤ should be used.

For example, if the Symbol is # and the divisibility is 2, the amount of 1234 units should be displayed as 12.34 #.

Nop

The Nop field is unrecognized.

Cenotaphs

Cenotaphs have the following effects:

  • All runes input to a transaction containing a cenotaph are burned.

  • If the runestone that produced the cenotaph contained an etching, the etched rune has supply zero and is unmintable.

  • If the runestone that produced the cenotaph is a mint, the mint counts against the mint cap and the minted runes are burned.

Cenotaphs may be created if a runestone contains an unrecognized even tag, an unrecognized flag, an edict with an output number greater than the number of inputs, a rune ID with block zero and nonzero transaction index, a malformed varint, a non-datapush instruction in the runestone output script pubkey, a tag without a following value, or trailing integers not part of an edict.

Executing the Runestone

Runestones are executed in the order their transactions are included in blocks.

Etchings

A runestone may contain an etching:

#![allow(unused)]
fn main() {
struct Etching {
  divisibility: Option<u8>,
  premine: Option<u128>,
  rune: Option<Rune>,
  spacers: Option<u32>,
  symbol: Option<char>,
  terms: Option<Terms>,
}
}

rune is the name of the rune to be etched, encoded as modified base-26 integer.

Rune names consist of the letters A through Z, with the following encoding:

NameEncoding
A0
B1
Y24
Z25
AA26
AB27
AY50
AZ51
BA52

And so on and so on.

Rune names AAAAAAAAAAAAAAAAAAAAAAAAAAA and above are reserved.

If rune is omitted a reserved rune name is allocated as follows:

#![allow(unused)]
fn main() {
fn reserve(block: u64, tx: u32) -> Rune {
  Rune(
    6402364363415443603228541259936211926
    + (u128::from(block) << 32 | u128::from(tx))
  )
}
}

6402364363415443603228541259936211926 corresponds to the rune name AAAAAAAAAAAAAAAAAAAAAAAAAAA.

If rune is present, it must be unlocked as of the block in which the etching appears.

Initially, all rune names of length thirteen and longer, up until the first reserved rune name, are unlocked.

Runes begin unlocking in block 840,000, the block in which the runes protocol activates.

Thereafter, every 17,500 block period, the next shortest length of rune names is continuously unlocked. So, between block 840,000 and block 857,500, the twelve-character rune names are unlocked, between block 857,500 and block 875,000 the eleven character rune names are unlocked, and so on and so on, until the one-character rune names are unlocked between block 1,032,500 and block 1,050,000. See the ord codebase for the precise unlocking schedule.

To prevent front running an etching that has been broadcast but not mined, if a non-reserved rune name is being etched, the etching transaction must contain a valid commitment to the name being etched.

A commitment consists of a data push of the rune name, encoded as a little-endian integer with trailing zero bytes elided, present in an input witness tapscript where the output being spent has at least six confirmations.

If a valid commitment is not present, the etching is ignored.

Minting

A runestone may mint a rune by including the rune's ID in the Mint field.

If the mint is open, the mint amount is added to the unallocated runes in the transaction's inputs. These runes may be transferred using edicts, and will otherwise be transferred to the first non-OP_RETURN output, or the output designated by the Pointer field.

Mints may be made in any transaction after an etching, including in the same block.

Transferring

Runes are transferred by edict:

#![allow(unused)]
fn main() {
struct Edict {
  id: RuneId,
  amount: u128,
  output: u32,
}
}

A runestone may contain any number of edicts, which are processed in sequence.

Before edicts are processed, input runes, as well as minted or premined runes, if any, are unallocated.

Each edict decrements the unallocated balance of rune id and increments the balance allocated to transaction outputs of rune id.

If an edict would allocate more runes than are currently unallocated, the amount is reduced to the number of currently unallocated runes. In other words, the edict allocates all remaining unallocated units of rune id.

Because the ID of an etched rune is not known before it is included in a block, ID 0:0 is used to mean the rune being etched in this transaction, if any.

An edict with amount zero allocates all remaining units of rune id.

An edict with output equal to the number of transaction outputs allocates amount runes to each non-OP_RETURN output in order.

An edict with amount zero and output equal to the number of transaction outputs divides all unallocated units of rune id between each non-OP_RETURN output. If the number of unallocated runes is not divisible by the number of non-OP_RETURN outputs, 1 additional rune is assigned to the first R non-OP_RETURN outputs, where R is the remainder after dividing the balance of unallocated units of rune id by the number of non-OP_RETURN outputs.

If any edict in a runestone has a rune ID with block zero and tx greater than zero, or output greater than the number of transaction outputs, the runestone is a cenotaph.

Note that edicts in cenotaphs are not processed, and all input runes are burned.

오디널 이론 자주 묻는 질문 (FAQ)

오디널 이론이란 무엇인가?

오디널 이론은 비트코인의 가장 작은 단위인 사토시에 일련번호를 할당하고 트랜잭션에서 사토시가 사용될 때 이를 추적하는 프로토콜이다.

이 일련번호는 예를 들어 804766073970493같이 큰 숫자이다. 비트코인의 ¹⁄₁₀₀₀₀₀₀₀₀₀인 모든 사토시에는 서수 번호가 있다.

오디널 이론은 사이드 체인, 별도의 토큰 또는 비트코인 변경을 필요로 하는가?

아니다! 오디널 이론은 현재 사이드 체인 없이도 작동하며, 필요한 유일한 토큰은 비트코인 자체이다.

오디널 이론의 장점은 무엇인가?

수집, 거래, 그리고 계획. 오디널 이론은 개별 사토시에게 신원을 부여하여 개별적으로 추적하고 수집품이나 화폐적 가치를 위해 거래할 수 있도록 한다.

오디널 이론은 또한 개별 사토시에 임의의 콘텐츠를 첨부하여 비트코인 고유의 디지털 아티팩트로 전환하는 프로토콜인 인스크립션을 가능하게 한다.

오디널 이론은 어떻게 작동하는가?

서수 번호는 채굴된 순서대로 사토시에 할당된다. 첫 번째 블록의 첫 번째 사토시는 서수 번호 0, 두 번째 사토시는 서수 번호 1, 첫 번째 블록의 마지막 사토시는 서수 번호 4,999,999,999를 갖는다.

사토시는 출력(output)에 존재하지만 트랜잭션은 출력을 파괴하고 새로운 출력을 생성하므로 오디널 이론은 알고리즘을 사용해 사토시가 트랜잭션의 입력에서 출력으로 이동하는 방식을 결정한다.

다행히도 이 알고리즘은 매우 간단하다.

사토시는 선입선출 순서로 전송된다. 트랜잭션의 입력은 사토시에 대한 목록으로, 출력은 사토시 수신을 기다리는 슬롯 목록으로 생각해 보자. 입력 사토시를 슬롯에 할당하려면 입력에 있는 각 사토시를 순서대로 가장 먼저 사용 가능한 출력 슬롯에 할당한다.

3개의 입력과 2개의 출력이 있는 트랜잭션을 가정해 보자. 입력은 화살표 왼쪽에 있고 출력은 오른쪽에 있으며 모두 값으로 레이블이 지정되어 있다:

[2] [1] [3] → [4] [2]

이제 동일한 트랜잭션에 각 입력에 포함된 사토시의 서수 번호와 각 출력 슬롯에 물음표로 레이블을 지정해 보자. 서수 번호는 크기가 크므로 문자로 표현해 보자:

[a b] [c] [d e f] → [? ? ? ?] [? ?]

어떤 사토시가 어떤 출력으로 이동하는지 파악하려면 입력된 사토시를 순서대로 살펴보고 각각 물음표에 할당하면 된다:

[a b] [c] [d e f] → [a b c d] [e f]

수수료는 어떻게 되는가? 좋은 질문이다! 동일한 트랜잭션에 이번에는 2사토시 수수료가 있다고 가정해 보자. 수수료가 있는 트랜잭션은 출력에서 받는 것보다 더 많은 사토시를 입력으로 전송하므로, 수수료를 지불하는 트랜잭션으로 만들기 위해 두 번째 출력을 제거하자:

[2] [1] [3] → [4]

사토시 e그리고 f는 이제 출력에 갈 곳이 없다:

[a b] [c] [d e f] → [a b c d]

따라서 블록을 채굴한 채굴자에게 수수료로 지급된다. BIP에 자세한 내용이 나와 있지만, 간단히 말해 트랜잭션이 지불한 수수료는 코인베이스 트랜잭션에 대한 추가 입력으로 취급되며, 이의 순서는 해당 트랜잭션이 블록에서 어떻게 정렬되는지에 따라서 정해진다. 해당 블록의 코인베이스 트랜잭션은 다음과 같이 보일 수 있다:

[SUBSIDY] [e f] → [SUBSIDY e f]

핵심적인 세부 정보는 어디에서 찾을 수 있는가?

BIP을 참조하자!

SAT 인스크립션을 "NFT"가 아닌 "디지털 아티팩트"라고 부르는 이유는 무엇인가?

인스크립션은 NFT이지만, 단순하고 시사하는 바가 많으며 친숙하기 때문에 대신 "디지털 아티팩트"라는 용어를 사용한다.

"디지털 아티팩트"라는 문구는 이 용어를 처음 들어본 사람에게도 매우 시사하는 바가 많은 표현이다. 이에 비해 NFT는 약어이며, 이 용어를 처음 들어본 사람이라면 무슨 뜻인지 알 수 없다.

또한 “NFT”(대체 불가능 토큰)는 금융 용어처럼 느껴지며, 여기서 쓰여지는 “대체 가능한”이라는 단어와 “토큰”이라는 단어의 의미 모두 금융적인 상황을 제외하고는 그 쓰임이 흔하지 않다.

SAT 인스크립션을 다음과 비교하면…

이더리움 NFT?

인스크립션은 항상 불변한다.

인스크립이 생성된 후에는 작성자나 소유자가 이를 수정할 수 있는 방법이 없다.

이더리움 NFT는 불변하는 것이 가능 하지만, 많은 경우 불변하지 않으며, 스마트 컨트랙트 소유자가 변경하거나 삭제할 수 있다.

특정 이더리움 NFT가 변경 불가능한지 확인하려면 컨트랙트 코드를 감사해야 하며, 이를 위해서는 EVM과 솔리디티 시맨틱에 대한 자세한 지식이 필요하다.

기술 전문가가 아닌 사용자가 특정 이더리움 NFT가 변경 가능한지 또는 변경 불가능한지 여부를 판단하는 것은 매우 어렵고, 이더리움 NFT 플랫폼은 NFT가 변경 가능한지 또는 변경 불가능한지, 컨트랙트 소스 코드가 확인 가능하고 감사를 받았는지 여부를 구분하기 위해 노력하지 않는다.

인스크립션 콘텐츠는 항상 온체인에 있다.

인스크립션은 오프체인 콘텐츠를 참조할 수 있는 방법이 없다. 따라서 콘텐츠가 손실되지 않기 때문에 인스크립션의 내구성이 높아지고, 인스크립션 작성자가 콘텐츠 크기에 비례하는 수수료를 지불해야 하기 때문에 희소성이 높아진다.

일부 이더리움 NFT 콘텐츠는 온체인에 있지만, 대부분은 오프체인에 있으며, IPFS나 Arweave와 같은 플랫폼이나 기존의 완전히 중앙화된 웹 서버에 저장되어 있다. IPFS에 저장된 콘텐츠는 지속적 사용이 보장되지 않으며, IPFS에 저장된 일부 NFT 콘텐츠는 이미 손실된 바 있다. Arweave와 같은 플랫폼은 취약한 경제적 가정에 의존하고 있으며, 이러한 경제적 가정이 더 이상 충족되지 않으면 파국적으로 실패할 가능성이 높다. 중앙화된 웹 서버는 언제든 사라질 수 있다.

평범한 사용자가 특정 이더리움 NFT의 콘텐츠가 어디에 저장되어 있는지 파악하는 것은 매우 어렵다.

인스크립션은 훨씬 더 간단하다.

이더리움 NFT는 이더리움 네트워크와 가상 머신에 의존하며 이는 매우 복잡하고 끊임없이 변화하며, 이전 버전과 호환되지 않는 하드포크를 통해 변경 사항을 도입한다.

반면에 인스크립션은 비트코인 블록체인에 의존하며 이는 상대적으로 단순하고 보수적이며 이전 버전과 호환되는 소프트 포크를 통해 변경 사항을 도입한다.

인스크립션이 더 안전하다.

인스크립션은 비트코인의 트랜잭션 모델을 이어받아 사용자가 서명하기 전에 트랜잭션이 전송하는 인스크립션을 정확히 확인할 수 있다. 인스크립션은 부분적으로 서명된 트랜잭션(PSBT)을 사용하여 판매할 수 있으며, 거래소나 마켓플레이스와 같은 제3자가 사용자를 대신하여 전송하도록 허용할 필요가 없다.

이에 비해 이더리움 NFT는 최종 사용자 보안 취약점으로 골머리를 앓고 있다. 트랜잭션에 블라인드 서명을 하고, 제3자 앱에 사용자 NFT에 대한 무제한 권한을 부여하고, 복잡하고 예측할 수 없는 스마트 콘트랙트와 상호작용하는 것은 흔한 일이다. 이는 이더리움 NFT 사용자에게 위험의 지뢰밭을 만들며, 이는 오디널 이론가들에게는 전혀 문제가 되지 않는다.

인스크립션은 더 희귀하다.

인스크립션을 발행하고, 전송하고, 보관하려면 비트코인이 필요하다. 이는 겉으로 보기에는 단점처럼 보이지만, 디지털 아티팩트의 존재 이유는 희소성이 높고 따라서 가치 있는 것이 되는 것이다.

반면, 이더리움 NFT는 한 번의 트랜잭션으로 사실상 무제한으로 발행할 수 있으므로 이는 본질적으로 그 희소성을 낮추고 따라서 잠재적으로 그 가치를 떨어뜨릴 수 있다.

인스크립션은 온체인 로열티를 지원하는 것처럼 가장하지 않는다.

온체인 로열티는 이론적으로는 좋은 아이디어이지만 실제로는 그렇지 않다. 복잡하고 침해적 제한 없이는 온체인에서 로열티 지급을 시행할 수 없다. 현재 이더리움 NFT 생태계는 로열티에 대한 혼란으로 어려움을 겪고 있으며, 플랫폼들이 경쟁적으로 로열티 지원을 없애고 있는 가운데 아티스트들에게 NFT의 장점으로 얘기되었던 온체인 로열티가 불가능하다는 현실을 공동으로 인식하고 있다.

인스크립션은 온체인 로열티 지원에 대한 거짓 약속을 하지 않음으로써 이러한 상황을 완전히 피하여 이더리움 NFT 상황의 혼란, 혼돈, 부정적 영향을 피할 수 있다.

인스크립션은 새로운 시장을 열어준다.

비트코인의 시가총액과 유동성은 이더리움보다 큰 폭으로 높다. 많은 비트코인 사용자는 단순성, 보안, 탈중앙화와 관련된 우려로 인해 이더리움 생태계와 상호작용하지 않는 것을 선호하기 때문에 이더리움 NFT에는 이러한 유동성의 상당 부분이 제공되지 않는다.

이러한 비트코인 사용자들은 이더리움 NFT보다 인스크립션에 더 관심을 가질 수 있으며, 새로운 종류의 수집가가 생겨나게 할 수 있다.

인스크립션에는 더 풍부한 데이터 모델이 있다.

인스크립션은 MIME 유형이라고도 하는 콘텐츠 유형과 임의의 바이트 문자열(string)인 콘텐츠로 구성된다. 이는 웹에서 사용되는 것과 동일한 데이터 모델이며, 인스크립션 콘텐츠가 웹과 함께 진화하여 기본 프로토콜을 변경하지 않고도 웹 브라우저에서 지원하는 모든 종류의 콘텐츠를 지원할 수 있도록 한다.

RGB 및 타로(Taro) 자산?

RGB와 타로는 모두 비트코인에 기반한 레이어2 자산 프로토콜이다. 인스크립션과 비교하면 훨씬 더 복잡하지만 훨씬 더 많은 기능을 갖추고 있다.

오디널 이론은 처음부터 디지털 아티팩트를 위해 설계된 반면, RGB와 타로의 주요 사용 사례는 대체 가능한 토큰이므로 인스크립션에 대한 사용자 경험은 RGB와 타로 NFT의 사용자 경험보다 더 단순하고 세련될 가능성이 높다.

RGB와 타로는 모두 오프체인에 콘텐츠를 저장하기 때문에 추가 인프라가 필요하고 손실될 수 있다. 반면, 인스크립션 콘텐츠는 온체인에 저장되므로 손실될 가능성이 없다.

오디널 이론, RGB, 타로는 모두 초기 단계이므로 추측에 불과하지만, 오디널 이론의 초점이 더 나은 콘텐츠 모델 같은 디지털 아티팩트에 대한 기능 측면에서 그리고 전 세계적으로 고유한 심볼과 같은 기능 측면에서 우위를 점하게 해줄수 있다.

카운터파티 자산(Counterparty assets)?

카운터파티는 일부 기능에 필요한 자체 토큰인 XCP를 보유하고 있으며, 이로 인해 대부분의 비트코인 사용자들은 이를 비트코인의 확장 또는 세컨드 레이어가 아닌 알트코인으로 간주한다.

오디널 이론은 처음부터 디지털 아티팩트를 위해 설계된 반면, 카운터파티는 주로 금융 토큰 발행을 위해 설계되었다.

누굴 위한 인스크립션…

예술가

인스크립션은 비트코인에 있다. 비트코인은 가장 높은 지위와 장기적인 생존 가능성을 가진 디지털 통화이다. 여러분의 작품이 미래에도 살아남을 수 있도록 보장하고 싶다면 인스크립션으로 발행하는 것보다 더 좋은 방법은 없다.

더 저렴한 온체인 스토리지. BTC당 20,000달러 그리고 최소 릴레이 수수료는 vByte당 1 사토시 일 때, 인스크립션 콘텐츠를 발행하는 데 드는 비용은 100만 바이트당 50달러이다.

인스크립션은 이르다! 인스크립션은 아직 개발 중이며 아직 메인넷에 출시되지 않았다. 따라서 얼리어답터가 되어 매체가 발전해 나가는 과정을 살펴볼 수 있는 기회이다.

인스크립션은 간단하다. 인스크립션은 스마트 컨트랙트를 작성하거나 이해할 필요가 없다.

인스크립션은 새로운 유동성을 열어준다. 인스크립션은 비트코인 보유자가 더 쉽게 접근할 수 있고 매력적으로 보일 수 있으며, 완전히 새로운 종류의 수집가들이 등장하게 할 수 있다.

인스크립션은 디지털 아티팩트를 위해 설계되었다. 인스크립션은 처음부터 NFT를 지원하도록 설계되었으며, 더 나은 데이터 모델과 전 세계적으로 고유한 심볼, 향상된 출처 증명과 같은 기능을 갖추고 있다.

인스크립션은 온체인 로열티를 지원하지 않는다. 이는 부정적이지만, 어떻게 보느냐에 따라 다르다. 온체인 로열티는 크리에이터에게 큰 혜택이었지만, 이더리움 NFT 생태계에 엄청난 혼란을 야기하기도 했다. 이제 생태계는 이 문제와 씨름하고 있으며, 로열티가 선택적인 미래를 향해 바닥을 향한 경쟁을 벌이고 있다. 인스크립션은 기술적으로 실현 불가능하기 때문에 온체인 로열티를 지원하지 않는다. 인스크립션을 생성하기로 결정한 경우, 향후 판매를 위해 인스크립션의 일부를 보류하여 향후 가치 상승의 혜택을 받거나 선택적 로열티를 존중하는 사용자에게 혜택을 제공하는 등 여러 가지 방법으로 이 제한을 해결할 수 있다.

수집가

인스크립션은 간단하고 명확하며 놀랄 일이 없다. 인스크립션은 항상 불변하고 온체인이며 특별한 실사가 필요하지 않다.

인스크립션은 비트코인에 있다. 사용자가 제어하는 비트코인 풀 노드를 통해 인스크립션의 위치와 속성을 쉽게 확인할 수 있다.

비트코인 사용자

이 부분을 이렇게 시작하고자 한다: 비트코인 네트워크가 하는 가장 중요한 일은 화폐를 탈중앙화하는 것이다. 오디널 이론을 포함한 다른 모든 사용 사례는 부차적인 것이다. 오디널 이론의 개발자들은 이를 이해하고 인정하며, 오디널 이론이 비트코인의 주요 사명에 조금이라도 도움이 된다고 믿는다.

알트코인 공간의 다른 많은 것들과 달리 디지털 아티팩트에는 장점이 있다. 물론 추악하고 어리석고 사기적인 NFT도 많이 있다. 하지만 환상적으로 창의적인 예술품도 많이 있으며, 예술품을 만들고 수집하는 것은 인류의 시작부터 이어져 온 일이며, 고대 기술인 무역과 화폐보다 더 오래 전부터 존재해 왔다.

비트코인은 안전하고 탈중앙화된 방식으로 디지털 아티팩트를 만들고 수집할 수 있는 놀라운 플랫폼을 제공하며, 같은 이유로 가치를 주고받을 수 있는 놀라운 플랫폼을 제공하며 동시에 같은 방식으로 사용자와 예술가를 보호한다.

오디널과 인스크립션은 비트코인 블록 공간에 대한 수요를 증가시켜 비트코인의 보안 예산을 증가시키며, 이는 블록 보조금이 무의미한 값으로 반감 되는 상황에서 비트코인이 수수료 의존적 보안 모델로 전환하는 것을 보호하는 데 필수적이다.

인스크립션 콘텐츠는 온체인에 저장되며, 따라서 인스크립션에 사용되는 블록 공간에 대한 수요는 무제한이다. 이는 모든 비트코인 블록 공간에 대한 최종구매자를 만든다. 이는 비트코인이 안전하게 유지되는 것을 보장해 주는 강력한 수수료 시장을 지원하는 데 도움이 될 것이다.

인스크립션은 또한 비트코인을 확장하거나 새로운 사용 사례에 사용할 수 없다는 내러티브를 반박한다. DLC, 페디민트, 라이트닝, 타로, RGB와 같은 프로젝트를 팔로우하신다면 이 내러티브가 거짓이라는 것을 알고 있겠지만, 인스크립션 제시하는 반론은 이해하기 쉽고 이 반론은 대중적이고 검증된 사용 사례인 NFT를 대상으로 하기 때문에 이를 판독하기 쉽게 한다.

저자들의 바람대로 인스크립션이 풍부한 역사를 지닌 인기가 높은 디지털 아티팩트라는 것이 증명된다면, 인스크립션은 비트코인 채택의 강력한 밑밥 역할을 하게 될 것이다: 재미있고 풍부한 예술 때문에 와보고 탈중앙화된 디지털 화폐 때문에 머무르자.

인스크립션은 블록 공간에 대한 매우 양성적인 수요의 원천이다. 예를 들어, 잠재적으로 대규모 스테이블코인 발행자가 비트코인 개발의 미래에 영향력을 행사할 수 있게 할수 있는 스테이블코인이나, 비트코인에 MEV를 적용할 기회를 도입하여 채굴을 중앙화 시킬 수 있는 탈중앙 금융(DeFi)과 달리, 비트코인 디지털 아트와 수집품이 비트코인을 손상시킬 수 있는 충분한 힘을 가진 개별 주체를 만들어 낼 가능성은 희박하다. 예술은 탈중앙화되어 있다.

인스크립션 사용자와 서비스 제공자는 비트코인 풀 노드를 운영하고, 인스크립션을 발행하고 추적하여 정직한 체인에 경제적 힘을 실어줄 동기부여를 받는다.

오디널 이론과 인스크립션은 비트코인의 대체 가능성에 의미 있는 영향을 미치지 않는다. 비트코인 사용자는 두 가지를 모두 무시해도 아무런 영향을 받지 않을 것이다.

우리의 바람은 오디널 이론이 비트코인을 강화하고 풍성하게 하며, 비트코인의 매력과 기능에 또 다른 차원을 부여하여 비트코인이 인류의 탈중앙화된 가치 저장소로서 이 주요 사용 사례를 더욱 효과적으로 수행할 수 있게 해 주는 것이다.

ord에 기여하기

권장 단계

  1. 작업하고 싶은 이슈를 찾아보자.
  2. 문제 해결을 위한 첫 번째 단계로 무엇이 좋을지 생각해 보자. 이는 코드, 연구, 제안의 형태가 될 수도 있고, 오래되었거나 애초에 좋은 아이디어가 아닌 경우 폐쇄를 제안하는 것일 수도 있다.
  3. 제안한 첫 번째 단계의 개요와 함께 문제에 대해 댓글을 달고 피드백을 요청하자. 물론 바로 코드나 테스트 작성을 시작할 수도 있지만, 이렇게 하면 문제가 오래되었거나, 명확하게 지정되지 않았거나, 다른 것에 의해 차단되었거나, 구현할 준비가 되지 않은 경우 잠재적으로 낭비될 수 있는 노력을 피할 수 있다.
  4. 문제에 코드 변경이나 버그 수정이 필요한 경우 테스트가 포함된 PR 초안을 오픈하고 피드백을 요청하자. 이렇게 하면 모든 사람이 수행해야 할 작업이나 문제 해결의 첫 단계가 무엇인지에 대해 동일한 정보를 공유할 수 있다. 또한 테스트가 필요하므로 테스트를 먼저 작성하면 변경 사항을 쉽게 테스트할 수 있는지 쉽게 확인할 수 있다.
  5. 테스트가 통과될 때까지 키보드를 무작위로 매시하고 코드를 제출할 준비가 될 때까지 리팩터링하자.
  6. PR을 리뷰할 준비가 된 것으로 표시한다.
  7. 필요에 따라 PR을 수정한다.
  8. 마지막으로 병합(merge)하자!

작은 것에서부터 시작

작은 변화는 빠르게 영향력을 발휘할 수 있게 해 주며, 잘못된 방법을 선택하더라도 많은 시간을 낭비하지 않을 수 있다.

작은 문제에 대한 몇 가지 아이디어:

  • 테스트 커버리지를 늘리는 새 테스트 또는 테스트 케이스 추가하자
  • 문서를 추가 또는 개선하자
  • 더 많은 조사가 필요한 이슈를 찾아서 조사를 하고 댓글에 요약하자
  • 오래된 이슈를 찾아서 닫을 수 있다고 댓글을 달자
  • 작업해서는 안 되는 이슈를 찾아서 왜 그렇게 생각하는지 자세히 설명하는 건설적인 피드백을 제공하자

일찍 그리고 자주 병합하자

큰 작업을 여러 개의 작은 단계로 나누어 개별적으로 진행하자. 버그가 있는 경우 실패한 테스트 무시를 추가하는 PR을 열 수 있다. 이를 병합할 수 있고 다음 단계로 버그를 수정하고 테스트를 무시 해제할 수 있다. 연구 또는 테스트를 수행하고 결과를 보고하자. 기능을 작은 하위 기능으로 나누고 한 번에 하나씩 구현하자.

큰 PR을 병합할 수 있는 작은 PR로 세분화하는 방법을 찾는 것은 연습해 볼 만한 가치가 있는 기술이다. 어려운 부분은 각 PR 자체가 프로잭트를 개선해야 한다는 것이다.

필자도 이 조언을 따르기 위해 노력하고 있으며, 그렇게 할 때 항상 더 나은 결과를 얻는다.

작은 변경 사항은 작성, 검토 및 병합이 빠르기 때문에 작성, 검토 및 병합에 오랜 시간이 걸리는 거대한 단일 PR을 작성하는 것보다 훨씬 더 재미있다. 작은 변경은 시간이 많이 걸리지 않으므로 작은 변경으로 작업을 중단해야 하는 경우에도 많은 시간이 소요되는 큰 변경에 비해 시간을 낭비하지 않을 수 있다. PR을 신속하게 적용하면 더 큰 개선을 위해 오랜 시간을 기다릴 필요 없이 즉시 프로젝트가 조금씩 개선된다. 작은 변경은 병합 갈등이 누적될 가능성이 적다. 아테네인들이 말했듯이 빠른 이는 하고싶은 것을 커밋하고, 느린 이는 해야할 것을 병합한다.

도움 받기

15분 이상 막혔을 경우 Rust 디스코드, 스택 익스체인지 (Stack Exchange), 프로젝트 이슈 또는 토론에서 도움을 요청하자.

가설 중심 디버깅을 사용하자

문제의 원인에 대한 가설을 세운다. 그 가설을 테스트하는 방법을 알아낸다. 해당 테스트를 수행한다. 테스트가 효과가 있다면 문제를 해결했거나 이제 문제를 해결하는 방법을 알게 된 것이다. 그렇지 않다면 새로운 가설로 반복한다.

오류 메시지에 주의를 기울이자

모든 오류 메시지를 읽고 경고를 무시하지 말자.

기부하는 방법

오디널스는 오픈소스이며 커뮤니티 펀딩을 받고 있다. 현재 ord의 리드 메인터너는 raphjaph이다. Raph의 ord 작업은 전적으로 기부금으로 충당된다. 가능하다면 기부에 동참하자!

비트코인 관련 기부 주소는 bc1q8kt9pyd6r27k2840l8g5d7zshz3cg9v6rfda0m248lva3ve5072q3sxelt이다. 인스크립션 관련 기부 주소는 bc1qn3map8m9hmk5jyqdkkwlwvt335g94zvxwd9aql7q3vdkdw9r5eyqvlvec0이다.

두 주소는 raphjaph, erin, rodarmor, ordinally가 키를 보유한 2-of-4 다중서명 지갑에 있다.

받은 기부금은 'ord'의 유지 및 개발 자금과 ordinals.com의 호스팅 비용으로 사용된다.

기부해 주어서 감사하다!

오디널 이론 설명서들

탐색기(익스플로러) 가이드, SAT 헌터 가이드, 인스크립션 가이드 등 설명서 목록을 보려면 목차를 참조하자.

오디널 탐색기

The ord binary includes a block explorer. We host an instance of the block explorer on mainnet at ordinals.com, on signet at signet.ordinals.com, and on testnet at testnet.ordinals.com. As of version 0.16.0 the wallet needs ord server running in the background. This is analogous to how bitcoin-cli needs bitcoind running in the background.

탐색기 실행

서버는 이것으로 로컬에서 실행할 수 있다:

ord server

포트를 지정하려면 --http-port 플래그를 추가한다:

ord server —http-port 8080

The JSON-API endpoints are enabled by default, to disable them add the --disable-json-api flag (see here for more info):

ord server --disable-json-api

검색

검색 상자에는 다양한 개체 표현이 허용된다.

블록

블록은 해시별로 검색할 수 있다 (예를 들어 제네시스 블록):

000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

트랜잭션

트랜잭션을 해시별로 검색할 수 있다 (예를 들어 제네시스 블록 코인베이스 트랜잭션):

4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b

출력

Transaction outputs can be searched by outpoint, for example, the only output of the genesis block coinbase transaction:

4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0

Sats

각 SAT은 정수로 검색할 수 있다. 이는 전체 비트코인 공급량 내에서 해당 SAT의 위치다:

2099994106992659

소수점 기준으로 검색할 수 있다. 이는 해당 블록과 해당 블록 내의 오프셋을 나타낸다:

481824.0

도표기법으로 검색할 수 있다. 이는 주기, 마지막 반감기 이후 블록, 마지막 난이도 조정 이후 블록, 블록 내 오프셋을 나타낸다:

1°0′0″0‴

이름으로 검색할 수 있다. 이는 문자 “a”부터 “z”까지를 사용하여 SAT을 base26으로 표기하는 법이다:

ahistorical

또는 백분위수로 검색할 수 있다. 이는 해당 SAT가 채굴되었을 때 이미 발행되었거나 앞으로 발행될 비트코인의 공급량의 비율이다:

100%

JSON-API

By default the ord server gives access to endpoints that return JSON instead of HTML if you set the HTTP Accept: application/json header. The structure of these objects closely follows what is shown in the HTML. These endpoints are:

  • /inscription/<INSCRIPTION_ID>
  • /inscriptions
  • /inscriptions/block/<BLOCK_HEIGHT>
  • /inscriptions/block/<BLOCK_HEIGHT>/<PAGE_INDEX>
  • /inscriptions/<FROM>
  • /inscriptions/<FROM>/<N>
  • /output/<OUTPOINT>
  • /sat/<SAT>

To get a list of the latest 100 inscriptions you would do:

curl -s -H "Accept: application/json" 'http://0.0.0.0:80/inscriptions'

To see information about a UTXO, which includes inscriptions inside it, do:

curl -s -H "Accept: application/json" 'http://0.0.0.0:80/output/bc4c30829a9564c0d58e6287195622b53ced54a25711d1b86be7cd3a70ef61ed:0'

Which returns:

{
  "value": 10000,
  "script_pubkey": "OP_PUSHNUM_1 OP_PUSHBYTES_32 156cc4878306157720607cdcb4b32afa4cc6853868458d7258b907112e5a434b",
  "address": "bc1pz4kvfpurqc2hwgrq0nwtfve2lfxvdpfcdpzc6ujchyr3ztj6gd9sfr6ayf",
  "transaction": "bc4c30829a9564c0d58e6287195622b53ced54a25711d1b86be7cd3a70ef61ed",
  "sat_ranges": null,
  "inscriptions": [
    "6fb976ab49dcec017f1e201e84395983204ae1a7c2abf7ced0a85d692e442799i0"
  ]
}

Wallet

각 SAT에 임의의 콘텐츠를 새길 수 있으며, 이로써 비트코인 지갑에 보관하고 비트코인 거래를 통해 전송할 수 있는 고유한 비트코인 자체 디지털 아티팩트를 만들 수 있다. 인스크립션은 비트코인만큼이나 내구성이 있고, 불변하며, 안전하고, 탈중앙화되어 있다.

인스크립션 작업에는 비트코인 블록체인의 현재 상태를 볼 수 있는 비트코인 풀 노드와 인스크립션을 생성하고 다른 지갑으로 인스크립션을 전송하는 트랜잭션을 만들 때 SAT 제어를 수행할 수 있는 지갑이 필요하다.

Bitcoin Core는 비트코인 풀노드와 지갑을 모두 제공한다. 그러나 Bitcoin Core 지갑은 인스크립션을 생성할 수 없으며, SAT 제어를 수행하지 않는다.

이를 위해서는 오디널 유틸리티인 ord가 필요하다. ord는 자체 지갑을 구현하지 않으므로 ord wallet 하위 명령은 Bitcoin Core 지갑과 상호작용한다.

이 가이드에서 다룰 토픽:

  1. Bitcoin Core 설치
  2. 비트코인 블록체인 동기화
  3. Bitcoin Core 지갑 만들기
  4. ord wallet receive을 사용하여 SAT 받기
  5. ord wallet inscribe으로 인스크립션 만들기
  6. ord wallet send로 인스크립션 보내기
  7. ord wallet receive로 인스크립션 받기
  8. Batch inscribing with ord wallet inscribe --batch

도움 받기

문제가 해결되지 않는다면, 오디널스 디스코드 서버에서 도움을 요청해 보거나 깃허브에서 관련 이슈토론을 확인해 보자.

Bitcoin Core 설치

Bitcoin Core는 bitcoincore.org다운로드 페이지에서 이용할 수 있다.

인스립션을 만들려면 Bitcoin Core 24 이상이 필요하다.

이 가이드에서는 Bitcoin Core 설치에 대해 자세히 다루지 않는다. Bitcoin Core가 설치되면 명령줄에서 bitcoind -version을 성공적으로 실행할 수 있어야 한다. bitcoin-qt는 사용하지 말라.

Bitcoin Core 설정하기

ord는 Bitcoin Core의 트랜잭션 인덱스와 rest 인터페이스가 필요하다.

트랜잭션 인덱스를 유지하도록 Bitcoin Core 노드를 설정하려면, bitcoin.conf에 다음을 추가한다:

txindex=1

또는 -txindex와 함께 bitcoind를 실행한다:

bitcoind -txindex

bitcoin.conf 파일 생성 또는 수정에 대한 자세한 내용은 여기에서 확인할 수 있다.

비트코인 블록체인 동기화

체인을 동기화하려면 다음을 실행한다:

bitcoind -txindex

...그리고 getblockcount가:

bitcoin-cli getblockcount

mempool.space block explorer와 같은 블록 탐색기의 블록 수와 일치할때까지 실행한다. ordbitcoind와 상호 작용하므로 ord을 사용할 때는 bitcoind를 백그라운드에서 실행하도록 두어야 한다.

블록체인은 약 600GB의 디스크 공간을 필요로 한다. 블록을 저장할 외장 드라이브가 있는 경우, 설정 옵션 blocksdir=<external_drive_path>를 사용한다. 이렇게 하면 쿠키 파일이 여전히 bitcoin-cliord가 찾을 수 있는 기본 위치에 있기 때문에 datadir 옵션을 사용하는 것보다 훨씬 간단하다.

트러블 슈팅

bitcoindbitcoin-cli -getinfo로 액세스할 수 있는지 그리고 이것이 완전히 동기화되었는지를 확인한다.

bitcoin-cli -getinfoCould not connect to the server을 반환하면 bitcoind가 실행되고 있지 않은 것이다.

rpcuser, rpcpassword 또는 rpcauthbitcoin.conf 파일에 설정되어 있지 않는 것을 확인하자. ord는 쿠키 인증에 사용을 요구한다. 비트코인 데이터 디렉토리에 .cookie 파일이 있는지 확인하자.

bitcoin-cli -getinfoCould not locate RPC credentials을 반환하면 쿠키 파일 위치를 지정해야 한다. 사용자 지정 데이터 디렉터리를 사용하는 경우(datadir 옵션을 지정) bitcoin-cli -rpccookiefile=<your_bitcoin_datadir>/.cookie -getinfo와 같이 쿠키 위치를 지정해야 한다. ord을 실행할 때는 --cookie-file=<your_bitcoin_datadir>/.cookie로 쿠키 파일 위치를 지정해야 한다.

bitcoin.conf 파일에 disablewallet=1없는 것을 확인하자. bitcoin-cli listwalletsMethod not found을 반환하면 지갑이 비활성화된 것이며 ord를 사용할 수 없다.

txindex=1이 설정되어 있는지 확인한다. bitcoin-cli getindexinfo를 실행하면 다음과 같은 결과가 반환되어야 한다

{
  "txindex": {
    "synced": true,
    "best_block_height": 776546
  }
}

만약 {}만 반환하면 txindex가 설정되지 않은 것이다. ”synced”: false를 반환하면 bitcoind가 여전히 txindex를 생성하고 있는 것이다. ”synced”: true가 될 때까지 기다렸다가 ord를 사용하라.

maxuploadtarget이 설정되어 있으면 ord 인덱스를 위해 블록을 가져오는 데 방해가 될 수 있다. 이를 제거하거나 whitebind=127.0.0.1:8333을 설정하라.

ord 설치

'ord` 유틸리티는 Rust로 작성되었으며 소스에서 빌드할 수 있다. 미리 빌드된 바이너리는 릴리스 페이지에서 사용할 수 있다.

명령줄에서 다음을 사용하여 미리 빌드된 최신 바이너리를 설치할 수 있다:

curl --proto '=https' --tlsv1.2 -fsLS https://ordinals.com/install.sh | bash -s

ord가 설치되면 다음을 실행할 수 있어야 한다:

ord --version

이것이 ord의 버전 번호를 출력한다.

Creating a Wallet

ord uses bitcoind to manage private keys, sign transactions, and broadcast transactions to the Bitcoin network. Additionally the ord wallet requires ord server running in the background. Make sure these programs are running:

bitcoind -txindex
ord server

To create a wallet named ord, the default, for use with ord wallet, run:

ord wallet create

This will print out your seed phrase mnemonic, store it somewhere safe.

{
  "mnemonic": "dignity buddy actor toast talk crisp city annual tourist orient similar federal",
  "passphrase": ""
}

If you want to specify a different name or use an ord server running on a non-default URL you can set these options:

ord wallet --name foo --server-url http://127.0.0.1:8080 create

To see all available wallet options you can run:

ord wallet help

Restoring and Dumping Wallet

The ord wallet uses descriptors, so you can export the output descriptors and import them into another descriptor-based wallet. To export the wallet descriptors, which include your private keys:

$ ord wallet dump
==========================================
= THIS STRING CONTAINS YOUR PRIVATE KEYS =
=        DO NOT SHARE WITH ANYONE        =
==========================================
{
  "wallet_name": "ord",
  "descriptors": [
    {
      "desc": "tr([551ac972/86'/1'/0']tprv8h4xBhrfZwX9o1XtUMmz92yNiGRYjF9B1vkvQ858aN1UQcACZNqN9nFzj3vrYPa4jdPMfw4ooMuNBfR4gcYm7LmhKZNTaF4etbN29Tj7UcH/0/*)#uxn94yt5",
      "timestamp": 1296688602,
      "active": true,
      "internal": false,
      "range": [
        0,
        999
      ],
      "next": 0
    },
    {
      "desc": "tr([551ac972/86'/1'/0']tprv8h4xBhrfZwX9o1XtUMmz92yNiGRYjF9B1vkvQ858aN1UQcACZNqN9nFzj3vrYPa4jdPMfw4ooMuNBfR4gcYm7LmhKZNTaF4etbN29Tj7UcH/1/*)#djkyg3mv",
      "timestamp": 1296688602,
      "active": true,
      "internal": true,
      "range": [
        0,
        999
      ],
      "next": 0
    }
  ]
}

An ord wallet can be restored from a mnemonic:

ord wallet restore --from mnemonic

Type your mnemonic and press return.

To restore from a descriptor in descriptor.json:

cat descriptor.json | ord wallet restore --from descriptor

To restore from a descriptor in the clipboard:

ord wallet restore --from descriptor

Paste the descriptor into the terminal and press CTRL-D on unix and CTRL-Z on Windows.

SAT 받기

인스크립션은 SAT로 수수료를 지불하는 일반 비트코인 거래를 사용하여 개별 SAT에 새김 됨으로 지갑에 약간의 SAT가 필요하다.

다음을 실행하여 ord 지갑에서 새 주소를 가져온다:

ord wallet receive

그리고 자금을 조금 보내자.

다음을 사용하여 펜딩 트랜잭션을 확인할 수 있다:

ord wallet transactions

트랜잭션이 컨펌되면 ord wallet outputs으로 트랜잭션 출력을 확인할 수 있다.

인스크립션 콘텐츠 만들기

SAT에는 모든 종류의 콘텐츠를 새길 수 있지만, ord 지갑은 ord 블록 탐색기에서 표시할 수 있는 콘텐츠 유형만 지원한다.

또한 인스크립션은 트랜잭션에 포함되므로 콘텐츠가 클수록 인스크립션 트랜잭션에서 지불해야 하는 수수료가 높아진다.

인스크립션 콘텐츠는 트랜잭션 증인에 포함되며, 증인 할인(witness discount)을 받는다. 인스크립트 트랜잭션이 지불할 대략의 수수료를 계산하려면 콘텐츠 크기를 4로 나눈 다음 수수료율을 곱하면 된다.

인스크립션 트랜잭션은 400,000 가중치 단위(weight unit) 미만이어야 하며, 그렇지 않으면 Bitcoin Core에서 릴레이 되지 않는다. 1바이트의 인스크립션 콘텐츠는 1 가중치 단위의 비용이 든다. 인스크립션 트랜잭션에는 인스크립션 콘텐츠만 포함되지 않으므로, 인스크립션 콘텐츠를 400,000 가중치 단위 미만으로 제한하라. 390,000 개의 가중치 단위미만은 안전할 것이다.

인스크립션 생성하기

FILE의 내용으로 인스크립션을 만들려면 다음을 실행한다:

ord wallet inscribe --fee-rate FEE_RATE --file FILE

Ord는 커밋 트랜잭션과 리빌 트랜잭션에 대한 두 개의 트랜잭션 ID와 인스크립션 ID를 출력한다. 인스크립션 ID는 TXIDiN 형식이며, 여기서 TXID는 리빌 트랜잭션의 트랜잭션 ID이고 N은 리빌 트랜잭션안에 있는 인스크립션의 인덱스이다.

커밋 트랜잭션은 인스크립션 콘텐츠가 포함된 탭스크립트(tapscript)에 커밋하고, 리빌 트랜잭션은 해당 탭스크립트에서 지출하여 체인에서 콘텐츠를 공개하고 해당 탭스크립트가 포함된 입력의 첫 번째 SAT에 인스크립션을 새긴다.

리빌 트랜잭션이 채굴될 때까지 기다린다. Mempool.space 블록 탐색기를 사용하여 커밋 및 리빌 트랜잭션의 상태를 확인할 수 있다.

리빌 트랜잭션이 채굴되면 다음을 실행할 때 인스크립션 ID가 출력되어야 한다:

ord wallet inscriptions

부모-자식 인스크립션

부모-자식 인스크립션은 구어체로 컬렉션이라고 하는 것을 가능하게 한다. 자세한 내용은 기원을 참조하자.

인스크립션을 다른 인스크립션의 자식으로 만들려면 부모 인스크립션이 새김되어 있고 지갑에 있어야 한다. 부모를 선택하려면 ord wallet inscriptions을 실행하고 인스크립션 ID(<PARENT_INSCRIPTION_ID>)를 복사한다.

이제 자식 인스크립션을 새기고 부모를 다음과 같이 지정한다:

ord wallet inscribe --fee-rate FEE_RATE --parent <PARENT_INSCRIPTION_ID> --file CHILD_FILE

이 관계는 소급하여 추가할 수 없으며, 부모는 자녀가 시작될 때 이미 존재해야 한다.

인스크립션 보내기

수신자에게 다음을 실행해 새 주소를 생성하도록 요청한다:

ord wallet receive

다음을 실행하여 인스크립션을 보낸다:

ord wallet send --fee-rate <FEE_RATE> <ADDRESS> <INSCRIPTION_ID>

다음을 실행하여 펜딩 트랜잭션을 확인한다:

ord wallet transactions

전송 트랜잭션이 확인되면 수신자는 다음을 실행하여 수신을 확인할 수 있다:

ord wallet inscriptions

Sending Runes

수신자에게 다음을 실행해 새 주소를 생성하도록 요청한다:

ord wallet receive

Send the runes by running:

ord wallet send --fee-rate <FEE_RATE> <ADDRESS> <RUNES_AMOUNT>

Where RUNES_AMOUNT is the number of runes to send, a : character, and the name of the rune. For example if you want to send 1000 of the EXAMPLE rune, you would use 1000:EXAMPLE.

ord wallet send --fee-rate 1 SOME_ADDRESS 1000:EXAMPLE

다음을 실행하여 펜딩 트랜잭션을 확인한다:

ord wallet transactions

Once the send transaction confirms, the recipient can confirm receipt with:

ord wallet balance

인스크립션 받기

다음을 사용하여 새 수신 주소를 생성한다:

ord wallet receive

발신자는 다음을 사용하여 인스크립션을 당신의 주소로 전송할 수 있다:

ord wallet send --fee-rate <FEE_RATE> ADDRESS INSCRIPTION_ID

다음을 실행하여 펜딩 트랜잭션을 확인한다:

ord wallet transactions

Once the send transaction confirms, you can confirm receipt by running:

ord wallet inscriptions

Batch Inscribing

Multiple inscriptions can be created at the same time using the pointer field. This is especially helpful for collections, or other cases when multiple inscriptions should share the same parent, since the parent can passed into a reveal transaction that creates multiple children.

To create a batch inscription using a batchfile in batch.yaml, run the following command:

ord wallet batch --fee-rate 21 --batch batch.yaml

Example batch.yaml

# example batch file

# inscription modes:
# - `same-sat`: inscribe on the same sat
# - `satpoints`: inscribe on the first sat of specified satpoint's output
# - `separate-outputs`: inscribe on separate postage-sized outputs
# - `shared-output`: inscribe on a single output separated by postage
mode: separate-outputs

# parent inscription:
parent: 6ac5cacb768794f4fd7a78bf00f2074891fce68bd65c4ff36e77177237aacacai0

# postage for each inscription:
postage: 12345

# allow reinscribing
reinscribe: true

# sat to inscribe on, can only be used with `same-sat`:
# sat: 5000000000

# rune to etch (optional)
etching:
  # rune name
  rune: THE•BEST•RUNE
  # allow subdividing super-unit into `10^divisibility` sub-units
  divisibility: 2
  # premine
  premine: 1000.00
  # total supply, must be equal to `premine + terms.cap * terms.amount`
  supply: 10000.00
  # currency symbol
  symbol: $
  # mint terms (optional)
  terms:
    # amount per mint
    amount: 100.00
    # maximum number of mints
    cap: 90
    # mint start and end absolute block height (optional)
    height:
      start: 840000
      end: 850000
    # mint start and end block height relative to etching height (optional)
    offset:
      start: 1000
      end: 9000
  # future runes protocol changes may be opt-in. this may be for a variety of
  # reasons, including that they make light client validation harder, or simply
  # because they are too degenerate.
  #
  # setting `turbo` to `true` opts in to these future protocol changes,
  # whatever they may be.
  turbo: true

# inscriptions to inscribe
inscriptions:
  # path to inscription content
- file: mango.avif
  # inscription to delegate content to (optional)
  delegate: 6ac5cacb768794f4fd7a78bf00f2074891fce68bd65c4ff36e77177237aacacai0
  # destination (optional, if no destination is specified a new wallet change address will be used)
  destination: bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
  # inscription metadata (optional)
  metadata:
    title: Delicious Mangos
    description: >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam semper,
      ligula ornare laoreet tincidunt, odio nisi euismod tortor, vel blandit
      metus est et odio. Nullam venenatis, urna et molestie vestibulum, orci
      mi efficitur risus, eu malesuada diam lorem sed velit. Nam fermentum
      dolor et luctus euismod.

- file: token.json
  # inscription metaprotocol (optional)
  metaprotocol: DOPEPROTOCOL-42069

- file: tulip.png
  destination: bc1pdqrcrxa8vx6gy75mfdfj84puhxffh4fq46h3gkp6jxdd0vjcsdyspfxcv6
  metadata:
    author: Satoshi Nakamoto

수집

현재 희귀한 SAT 및 인스크립션(이하 오디널)을 안전하게 보관하고 전송하는 데에 필수인 SAT콘트롤 및 SAT선택을 지원하는 지갑은 ord가 유일하다.

오디널을 주고받고 보관하는 권장된 방법은 ord를 사용하는 것이지만, 조금만 주의하면 다른 지갑으로 오디널을 안전하게 보관하고 경우에 따라서는 전송하는 것도 가능하다.

일반적으로, 지원되지 않는 지갑에서 오디널을 받는 것은 위험하지 않다. 오디널은 모든 비트코인 주소로 전송할 수 있으며, 오디널이 포함된 UTXO가 사용되지 않는 한 안전하다. 그러나 해당 지갑이 비트코인을 전송하는 데 사용되는 경우, 해당 지갑은 오디널이 포함된 UTXO를 입력으로 선택해 인스크립션을 보내거나 수수료로 사용할 수 있다.

이 핸드북에는 스패로우 월렛를 사용해 ord와 호환되는 지갑을 만드는 가이드가 있다.

이 가이드를 따르는 경우, 오디널 전송을 피하기 위해 수동으로 코인선택을 하지 않는 한, 생성한 지갑을 사용해 BTC를 전송해서는 안 된다는 점에 유의하기 바란다.

스패로우 월렛으로 인스크립션과 오디널 수집하기

ord 지갑을 설정할 수 없거나 아직 설정하지 않은 사용자는 해당 지갑에서 지출하는 방식에 매우 주의를 기울인다면 대체 비트코인 지갑으로 인스크립션과 오디널을 받을 수 있다.

이 가이드는 ord와 호환되며 나중에 ord로 가져오기 할 수 있는 스패로우 월렛을 사용해 지갑을 어떻게 생성하는지에 기본 단계를 설명한다

⚠️⚠️ 경고!! ⚠️⚠️

일반적으로 이 방법을 사용하는 경우, 이 지갑을 스패로우 소프트웨어에 사용해 수신 전용(receive-only) 지갑으로 사용해야 한다.

어떻게 하는지 확실하지 않다면 이 지갑에서 사토시를 사용(spend) 하지 말자. 이 경고에 주의하지 않으면 실수로 오디널과 인스크립션 대한 액세스를 아주 쉽게 잃을 수 있다.

지갑 설정 및 수신하기

릴리즈 페이지에서 당신 운영체제의 맞는 스패로우 월렛을 다운로드한다.

File -> New Wallet을 선택하고 ord라는 새 지갑을 생성한다.

Script TypeTaproot (P2TR)로 변경하고 New or Imported Software Wallet 옵션을 선택한다.

Use 12 Words을 선택한 다음 Generate New를 클릭한다. 비밀번호는 비워둔다.

새로운 12단어 BIP39 시드 문구가 생성된다. 지갑에 액세스하기 위한 백업용이므로 안전한 곳에 적어두자. 절대로 이 시드 문구를 다른 사람에게 공유하거나 보여주지 말자.

시드 문구를 적었으면 Confirm Backup을 클릭한다.

적어둔 시드 문구를 다시 입력한 다음 Create Keystore을 클릭한다.

Import Keystore를 클릭한다.

Apply를 클릭한다. 원하는 경우 지갑의 비밀번호를 설정한다.

이제 ord와 호환되는 지갑을 갖게 되었으며, BIP39 시드 문구를 사용하여 ord로 가져오기 할 수 있다. 오디널 또는 인스크립션을 받으려면 Receive 탭을 클릭하고 새 주소를 복사한다.

수신을 원할 때마다 기존 주소를 재사용하지 말고 새 주소를 사용해야 한다.

비트코인은 다른 블록체인 지갑들과 달리 새 주소를 무제한으로 생성할 수 있다는 점을 유의하자. Get Next Address 버튼을 클릭하면 새 주소를 생성할 수 있다. 앱의 Addresses 탭에서 모든 주소를 확인할 수 있다.

각 주소에 레이블(label)을 추가하여 사용 용도를 추적할 수 있다.

수신된 인스크립션 확인하기/보기

인스크립션을 받으면 스패로우의 Transactions 탭에 새 트랜잭션이 표시되고, UTXOs 탭에 새 UTXO가 표시된다.

처음에 이 트랜잭션은 "미확인”(“Unconfirmed”) 상태일 수 있으며, 완전히 수신하려면 이 트랜잭션이 비트코인 블록으로 채굴될 때까지 기다려야 한다.

트랜잭션의 상태를 추적하려면 트랜잭션을 마우스 오른쪽 버튼으로 클릭하고 Copy Transaction ID를 선택한 다음 해당 트랜잭션 ID를 mempool.space에 붙여넣기 하면 된다.

트랜잭션이 확인되면 UTXOs 탭으로 이동하여 확인하려는 UTXO를 찾아 Output을 마우스 오른쪽 버튼으로 클릭하고 Copy Transaction Output를 선택하여 인스크립션의 유효성을 검사하고 확인할 수 있다. 그런 다음 이 트랜잭션 출력 ID를 ordinals.com 검색에 붙여넣을 수 있다.

UTXO 동결하기

위에서 설명한 것처럼, 각 인스크립션은 미사용 트랜잭션 출력값(UTXO)에 저장된다. 실수로 인스크립션을 사용하지 않도록 매우 주의해야 하며, 이런 일이 발생하지 않도록 하는 한 가지 방법은 UTXO를 동결(freeze)하는 것이다.

이렇게 하려면 UTXOs 탭으로 이동하여 동결하려는 UTXO를 찾은 다음 Output을 마우스 오른쪽 버튼으로 클릭하고 Freeze UTXO을 선택한다.

이 UTXO(인스크립션)는 이제 동결을 해제할 때까지 스패로우 지갑 내에서 사용할 수 없다.

ord 지갑으로 가져오기

For details on setting up Bitcoin Core and the ord wallet check out the Wallet Guide

ord를 설정할 때 ord wallet create을 실행하여 새로운 지갑을 생성하는 대신, 스패로우 월렛에서 생성한 시드 문구와 ord wallet restore “BIP39 SEED PHRASE”를 사용하여 기존 지갑을 가져오기 할 수 있다.

현재 가져오기 한 지갑이 블록체인에 대해 자동으로 재스캔되지 않는 버그가 있다. 이 문제를 해결하려면 bitcoin core cli(bitcoin-cli -rpcwallet=ord rescanblockchain 767430)를 사용하여 수동으로 재스캔을 트리거해야 한다

그런 다음 ord wallet inscriptions을 사용하여 지갑의 인스크립션을 확인할 수 있다

이전에 ord로 지갑을 생성한 적이 있다면 기본 이름의 지갑이 이미 있을 것이므로 가져오기 한 지갑에 다른 이름을 지정해야 한다. 모든 ord 명령에 --wallet 매개변수를 사용하여 다른 지갑을 참조할 수 있다. 예시:

ord wallet --name ord_from_sparrow wallet restore --from mnemonic

ord wallet --name ord_from_sparrow wallet inscriptions

bitcoin-cli -rpcwallet=ord_from_sparrow rescanblockchain 767430

스패로우 월렛으로 인스크립션 보내기

⚠️⚠️ 경고 ⚠️⚠️

Bitcoin Core 노드를 설정하고 ord 소프트웨어를 실행하는 것을 적극 권장하지만, 스패로우 월렛에서 안전한 방법으로 인스크립션을 전송할 수 있는 몇 가지 제한된 방법이 있다. 이 방법은 권장되지 않으며, 자신이 무엇을 하는지 완전히 이해하는 경우에만 이 방법을 사용해야 한다는 점에 유의하기 바란다.

ord 소프트웨어를 사용하면 인스크립션 전송을 자동으로 안전하게 처리할 수 있으므로 여기서 설명하는 복잡성을 상당 부분 제거할 수 있다.

⚠️⚠️ 추가 경고 ⚠️⚠️

스패로우 인스크립션 지갑을 사용해 인스크립션이 아닌 일반 비트코인을 송금하지 말자. 일반적인 비트코인 거래를 해야 하는 경우 스패로우에서 별도의 지갑을 설정하고 인스크립션 지갑을 따로 보관할 수 있다.

비트코인의 UTXO 모델

트랜잭션을 전송하기 전에 비트코인의 미사용 트랜잭션 출력값(UTXO) 시스템에 대한 올바른 멘털 모델을 갖추는 것이 중요하다. 비트코인의 작동 방식은 이더리움과 같은 다른 블록체인과 근본적으로 다르다. 이더리움에서는 일반적으로 이더를 저장하는 단일 주소가 있으며, 이더를 구분할 수 없으므로 이것은 단지 그 주소에 있는 총금액의 단일 값일 뿐이다. 비트코인은 매번 수신 때마다 지갑에 새 주소를 생성한다는 점에서 매우 다르게 작동하며, 지갑에 있는 주소로 SAT를 받을 때마다 새로운 UTXO를 생성하게 된다. 각 UTXO는 개별적으로 보고 관리할 수 있다. 사용하고자 하는 특정 UTXO를 선택할 수 있으며, 특정 UTXO를 사용하지 않도록 선택할 수도 있다.

일부 비트코인 지갑은 이러한 수준의 세부 정보를 노출하지 않으며, 지갑에 있는 모든 비트코인의 합산된 가치만 보여준다. 하지만 인스크립션을 전송할 때는 UTXO 제어가 가능한 스패로우와 같은 지갑을 사용하는 것이 중요하다.

보내기 전에 인스크립션 검사하기

앞서 설명한 것처럼 인스크립션은 SAT에 새겨지며, SAT는 UTXO 내에 저장된다. UTXO는 특정 값의 사토시 수(출력 값)를 가진 사토시의 모음이다. 일반적으로 (항상 그런 것은 아니지만) 인스크립션은 UTXO의 첫 번째 사토시에 새겨진다.

전송하기 전에 인스크립션을 검사할 때 가장 중요하게 확인해야 할 것은 UTXO의 사토시 중 인스크립션이 새겨진 사토시가 어느 것인지다.

이것을 하려면 위에서 설명한 수신된 인스크립션 확인하기/보기를 따라 ordinals.com에서 해당 인스크립션에 대한 인스크립션 페이지를 찾을 수 있다

여기에서 다음과 같은 해당 인스크립션에 대한 메타데이터를 찾을 수 있다:

여기서 확인해야 할 몇 가지 중요한 사항이 있다:

  • output 식별자가 전송하려는 UTXO의 식별자와 일치한
  • 인스크립션의 offset0이다 (이는 인스크립션이 UTXO의 첫 번째 SAT에 위치한다는 의미)
  • output_value에 트랜잭션 전송 수수료(우송료)를 충당할 수 있는 충분한 SAT가 있는지 확인한다. 필요한 정확한 금액은 트랜잭션에 대해 선택할 수수료율에 따라 다르다

위의 모든 사항이 당신 인스크립션에 해당하면 아래 방법을 사용하여 인스크립션을 보내도 안전할 것이다.

⚠️⚠️ 특히 offset 값이 0이 아닌 경우 인스크립션을 보낼 때 매우 주의하라. 이 경우 이 방법을 권장하지 않는다. 자신이 무엇을 하고 있는지 모르는 상태에서 이 방법을 사용하면 실수로 비트코인 채굴자에게 인스크립션을 전송할 수 있기 때문이다.

인스크립션 보내기

인스크립션을 보내려면 UTXOs 탭으로 이동하여 이전에 유효성을 확인한 인스크립션이 포함된 UTXO를 찾는다.

이전에 UXTO를 동결했다면 마우스 오른쪽 버튼으로 클릭한 후 동결 해제해야 한다.

전송하려는 UTXO를 선택하고, 이 UTXO 이 선택되어 있는지 확인한다. 인터페이스에 UTXO 1/1이 표시될 것이다. 이 것이 확인되면 Send Selected를 누르면 된다.

그러면 트랜잭션 생성(create transaction) 인터페이스가 표시된다. 안전한 송금인지 확인하기 위해 여기서 확인해야 할 몇 가지 사항이 있다:

  • 트랜잭션에는 입력(input)이 1개만 있어야 하며, 이 입력은 전송하려는 레이블이 있는 UTXO여야 한다
  • 트랜잭션에는 출력(output)이 1개만 있어야 하며 이는 인스크립션을 보낼 주소/레이블이다

예를 들어 입력이 여러 개이거나 출력이 여러 개인 등 거래가 조금이라도 다르게 보인다면 안전한 송금이 아닐 수 있으니, 더 많은 정보를 파악하거나 ord 지갑으로 가져오기 할 수 있을 때까지 전송을 중단해야 한다.

적절한 트랜잭션 수수료를 설정해야 하며, 보통 스패로우에서 합리적인 수수료를 추천해 주지만, 트랜잭션 전송에 대한 권장 수수료율을 확인하려면 mempool.space에서 확인할 수도 있다.

받는 사람 주소에 레이블을 추가해야 하는데, alice address for inscription #123와 같은 레이블이 이상적이다.

위의 확인사항을 통해 안전한 트랜잭션인지 확인하고 송금에 확신이 들면 Create Transaction을 클릭한다.

여기서도 거래가 안전한지 다시 한 번 확인할 수 있으며, 확신이 들면 Finalize Transaction for Signing을 클릭한다.

여기에서 Sign을 누르기 전에 모든 것을 다시 한 번 확인할 수 있다.

그리고 실제로 Broadcast Transaction을 누르기 전에 모든 것을 확인할 수 있는 마지막 기회가 주어진다. 트랜잭션을 브로드캐스트하면 비트코인 네트워크로 전송되고 멤풀로 전파되기 시작한다.

트랜잭션의 상태를 추적하려면 Transaction Id (Txid)를 복사하여 mempool.space에 붙여넣으면 된다

트랜잭션이 확인되면 ordinals.com에서 인스크립션 페이지를 확인하여 새 출력 위치(output location) 및 주소로 이동했는지 확인할 수 있다.

트러블 슈팅

스패로우 지갑에 트랜잭션/UTXO가 표시되지 않지만, 나는 mempool.space에서는 볼 수 있다!

지갑이 비트코인 노드에 연결되어 있는지 확인하자. 이를 확인하려면 Preferences-> Server 설정으로 이동하여 Edit Existing Connection을 클릭한다.

여기에서 노드를 선택하고 Test Connection를 클릭하여 스패로우가 성공적으로 연결할 수 있는지 확인할 수 있다.

중재

ord에는 블록 탐색기가 포함되어 있으며, ord server로 로컬에서 실행할 수 있다.

블록 탐색기를 통해 인스크립션을 볼 수 있다. 인스크립션은 사용자가 생성한 콘텐츠로, 그 콘텐츠가 불쾌감을 주거나 불법일 수 있다.

오디널스 블록 탐색기 인스턴스를 운영하는 각 개인은 불법 콘텐츠에 대한 자신의 책임을 이해하고 자신의 인스턴스에 적합한 중재 정책을 결정할 책임이 있다.

특정 인스크립션이 ord 인스턴스에 표시되지 않도록 하려면 --config 옵션을 사용해 로드되는 YAML 구성 파일에 포함할 수 있다.

인스크립션을 숨기려면 먼저 숨기려는 인스크립션 ID를 사용하여 구성 파일을 만든다:

hidden:
- 0000000000000000000000000000000000000000000000000000000000000000i0

'ord' 구성 파일의 권장 이름은 'ord.yaml'이지만 어떤 파일 이름도 사용할 수 있다.

그런 다음 서버를 시작할 때 --config에 파일을 전달한다:

ord --config ord.yaml server

—config 옵션은 ord 뒤에 오지만 server 하위 명령 앞에 온다는 점을 유의하자.

구성 파일의 변경 사항을 로드하려면 ord를 다시 시작해야 한다.

ordinals.com

ordinals.com 인스턴스는 systemd를 사용하여 ord라고 하는 ord server 서비스를 실행하며, 구성 파일은 /var/lib/ord/ord.yaml에 있다.

ordinals.com에서 인스크립션을 숨기려면:

  1. SSH 사용하여 서버에 접속한다
  2. 인스크립션 ID를 /var/lib/ord/ord.yaml에 추가한다
  3. systemctl restart ord로 서비스를 다시 시작한다
  4. journalctl -u ord로 재시작을 모니터링한다

현재 ord는 재시작 속도가 느리기 때문에 사이트가 즉시 온라인 상태로 돌아오지 않을 것이다.

재인덱싱

때때로 ord 데이터베이스를 재인덱싱해야 하는 경우가 있는데, 이는 데이터베이스를 삭제하고 ord index update 또는 ord server를 사용하여 인덱싱 프로세스를 다시 시작해야 함을 의미한다. 재인덱싱해야 하는 이유는 다음과 같다:

  1. 데이터베이스 체계를 변경하는 ord의 새로운 주요 릴리스
  2. 데이터베이스가 어떻게든 손상되었을 때

ord가 사용하는 데이터베이스는 redb이므로 인덱스에 index.redb로 기본 파일 이름을 지정한다. 기본적으로 이 파일은 운영 체제에 따라 다른 위치에 저장된다.

PlatformValue예제
Linux$XDG_DATA_HOME/ord 또는 $HOME/.local/share/ord/home/alice/.local/share/ord
macOS$HOME/Library/Application Support/ord/Users/Alice/Library/Application Support/ord
Windows{FOLDERID_RoamingAppData}\ordC:\Users\Alice\AppData\Roaming\ord

따라서 MacOS에서 데이터베이스를 삭제하고 재인덱스하려면 터미널에서 다음 명령을 실행해야 한다:

rm ~/Library/Application Support/ord/index.redb
ord index update

물론 ord --datadir <DIR> index update로 데이터 디렉터리의 위치를 직접 설정하거나 ord --index <FILENAME> index update로 특정 파일 이름과 경로를 지정할 수도 있다.

SAT 헌팅

오디널 헌팅은 어렵지만 보람이 있다. 희귀하고 이색적인 SAT의 향기가 풍기는 UTXO가 가득한 지갑을 소유했을 때의 기분은 그 무엇과도 비교할 수 없다.

오디널은 사토시를 나타내는 숫자이다. 모든 사토시에는 서수가 있고 모든 서수에는 사토시가 있다.

준비

시작하기 전에 몇 가지 준비해야 할 사항이 있다.

  1. 첫째, 트랜잭션 인덱스가 있는 동기화된 Bitcoin Core 노드가 필요하다. 트랜잭션 인덱싱을 활성화하려면 명령줄에 -txindex를 입력한다:

    bitcoind -txindex
    

    또는 다음을 Bitcoin configuration file에 입력한다:

    txindex=1
    

    이를 실행하고 체인 끝을 따라잡을 때까지 기다린 후 다음 명령을 입력하면 현재 블록 높이를 출력할 것이다:

    bitcoin-cli getblockcount
    
  2. 둘째, 동기화된 ord 인덱스가 필요하다.

    • the repo에서 ord의 사본을 가져오자.

    • Run ord --index-sats server. It should connect to your bitcoin core node and start indexing.

    • Once it has finished indexing, leave the server running and submit new ord commands in a separate terminal session.

  3. 셋째, 검색하려는 UTXO가 있는 지갑이 필요하다.

희귀 오디널스 검색하기

Bitcoin Core 지갑에서 희귀 오디널스 검색하기

ord wallet 명령은 Bitcoin Core의 RPC API를 감싸는 래퍼일 뿐이므로 Bitcoin Core 지갑에서 희귀한 오디널스를 검색하는 것은 쉽다. 지갑의 이름이 foo이라는 가정하에:

  1. 지갑을 로드한다:

    bitcoin-cli loadwallet foo
    
  2. 희귀한 오디널스 지갑 foo의 UTXO를 표시한다:

    ord --index-sats wallet --name foo sats
    

Bitcoin Core 지갑이 아닌 지갑에서 희귀 오디널스 검색하기

ord wallet 명령은 Bitcoin Core의 RPC API를 감싸는 래퍼일 뿐이므로, Bitcoin Core가 아닌 지갑에서 희귀 오디널스를 검색하려면 지갑의 기술자(discriptors)를 Bitcoin Core로 가져오기 해야 한다.

기술자는 지갑이 개인 키와 공개 키를 생성하는 방법을 설명한다.

지갑의 공개 키에 대한 기술자만 Bitcoin Core로 가져와야 하며, 개인 키는 가져오지 않아야 한다.

지갑의 공개 키 기술자가 유출되면 공격자가 지갑 주소를 볼 수 있지만 자금은 안전할 것이다.

지갑의 개인 키 기술자가 유출되면 공격자가 지갑에서 자금을 탈취할 수 있다.

  1. 희귀 오디널스를 검색하려는 지갑에서 지갑 기술자를 가져온다. 다음과 같은 형태일 것이다:

    wpkh([bf1dd55e/84'/0'/0']xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/0/*)#csvefu29
    
  2. ‘foo-watch-only’라는 이름으로 Watch-only 지갑을 생성한다:

    bitcoin-cli createwallet foo-watch-only true true
    

    당신 마음대로 foo-watch-only보다 더 좋은 이름으로 지어주자!

  3. foo-watch-only 지갑을 로드한다:

    bitcoin-cli loadwallet foo-watch-only
    
  4. 지갑 기술자를 'foo-watch-only'로 가져온다:

    bitcoin-cli importdescriptors \
      '[{ "desc": "wpkh([bf1dd55e/84h/0h/0h]xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/0/*)#tpnxnxax", "timestamp":0 }]'
    

    지갑이 처음 트랜잭션을 받기 시작한 유닉스 타임스탬프를 알고 있다면, 0 대신 ”timestamp” 값에 사용할 수 있다. 이렇게 하면 Bitcoin Core가 당신 지갑의 UTXO를 검색하는 데 걸리는 시간을 줄일 수 있다.

  5. 모든 것이 제대로 되었는지 확인한다:

    bitcoin-cli getwalletinfo
    
  6. 당신 지갑의 희귀 오디널스를 표시한다:

    ord wallet sats
    

다중 경로 기술자를 내보내기 하는 지갑에서 희귀 오디널스 검색하기

일부 기술자는 꺾쇠 괄호(예: <0;1>)를 사용하여 하나의 기술자 안에 다수에 경로를 기술한다. 다중 경로 기술자는 아직 Bitcoin Core에서 지원되지 않으므로, 먼저 다수에 기술자들로 변환한 다음 Bitcoin Core로 해당 기술자들을 가져오기 해야 한다.

  1. 먼저 지갑에서 다중 경로 기술자를 가져온다. 다음과 같은 형태가 될 것이다:

    wpkh([bf1dd55e/84h/0h/0h]xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/<0;1>/*)#fw76ulgt
    
  2. 수신 주소 경로에 대한 기술자를 만든다:

    wpkh([bf1dd55e/84'/0'/0']xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/0/*)
    

    그리고 주소 변경 경로에 대한 기술자를 만든다:

    wpkh([bf1dd55e/84'/0'/0']xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/1/*)
    
  3. 수신 주소 기술자의 체크섬(이 경우 tpnxnxax)을 가져와 기록한다:

    bitcoin-cli getdescriptorinfo \
      'wpkh([bf1dd55e/84h/0h/0h]xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/0/*)'
    
    {
      "descriptor": "wpkh([bf1dd55e/84'/0'/0']xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/0/*)#csvefu29",
      "checksum": "tpnxnxax",
      "isrange": true,
      "issolvable": true,
      "hasprivatekeys": false
    }
    

    그리고 변경 주소 설명자의 체크섬(이 경우 64k8wnd7)를 가져와 기록한다:

    bitcoin-cli getdescriptorinfo \
      'wpkh([bf1dd55e/84h/0h/0h]xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/1/*)'
    
    {
      "descriptor": "wpkh([bf1dd55e/84'/0'/0']xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/1/*)#fyfc5f6a",
      "checksum": "64k8wnd7",
      "isrange": true,
      "issolvable": true,
      "hasprivatekeys": false
    }
    
  4. 기술자를 가져오기 할 지갑을 로드한다:

    bitcoin-cli loadwallet foo-watch-only
    
  5. 이제 올바른 체크섬과 기술자를 Bitcoin Core로 가져오기 한다.

    bitcoin-cli \
     importdescriptors \
     '[
       {
         "desc": "wpkh([bf1dd55e/84h/0h/0h]xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/0/*)#tpnxnxax"
         "timestamp":0
       },
       {
         "desc": "wpkh([bf1dd55e/84h/0h/0h]xpub6CcJtWcvFQaMo39ANFi1MyXkEXM8T8ZhnxMtSjQAdPmVSTHYnc8Hwoc11VpuP8cb8JUTboZB5A7YYGDonYySij4XTawL6iNZvmZwdnSEEep/1/*)#64k8wnd7",
         "timestamp":0
       }
     ]'
    

    지갑이 처음 트랜잭션을 받기 시작한 유닉스 타임스탬프를 알고 있다면, 0 대신 ”timestamp” 값에 사용할 수 있다. 이렇게 하면 Bitcoin Core가 당신 지갑의 UTXO를 검색하는 데 걸리는 시간을 줄일 수 있다.

  6. 모든 것이 제대로 되었는지 확인한다:

    bitcoin-cli getwalletinfo
    
  7. 당신 지갑의 희귀 오디널스를 표시한다:

    ord wallet sats
    

기술자 내보내기

스패로우 월렛

Settings 탭으로 이동한 다음 Script Policy로 이동한 후 편집 버튼을 눌러 기술자를 표시한다.

오디널스 전송하기

The ord wallet supports transferring specific satoshis by using the name of the satoshi. To send the satoshi zonefruits, do:

ord wallet send <RECEIVING_ADDRESS> zonefruits --fee-rate 21

You can also use the bitcoin-cli commands createrawtransaction, signrawtransactionwithwallet, and sendrawtransaction, but this method can be complex and is outside the scope of this guide.

Settings

ord can be configured with the command line, environment variables, a configuration file, and default values.

The command line takes precedence over environment variables, which take precedence over the configuration file, which takes precedence over defaults.

The path to the configuration file can be given with --config <CONFIG_PATH>. ord will error if <CONFIG_PATH> doesn't exist.

The path to a directory containing a configuration file name named ord.yaml can be given with --config-dir <CONFIG_DIR_PATH> or --datadir <DATA_DIR_PATH> in which case the config path is <CONFIG_DIR_PATH>/ord.yaml or <DATA_DIR_PATH>/ord.yaml. It is not an error if it does not exist.

If none of --config, --config-dir, or --datadir are given, and a file named ord.yaml exists in the default data directory, it will be loaded.

For a setting named --setting-name on the command line, the environment variable will be named ORD_SETTING_NAME, and the config file field will be named setting_name. For example, the data directory can be configured with --datadir on the command line, the ORD_DATA_DIR environment variable, or data_dir in the config file.

See ord --help for documentation of all the settings.

ord's current configuration can be viewed as JSON with the ord settings command.

Example Configuration

# example config

# see `ord --help` for setting documentation

bitcoin_data_dir: /var/lib/bitcoin
bitcoin_rpc_password: bar
bitcoin_rpc_url: https://localhost:8000
bitcoin_rpc_username: foo
chain: mainnet
commit_interval: 10000
config: /var/lib/ord/ord.yaml
config_dir: /var/lib/ord
cookie_file: /var/lib/bitcoin/.cookie
data_dir: /var/lib/ord
first_inscription_height: 100
height_limit: 1000
hidden:
- 6fb976ab49dcec017f1e201e84395983204ae1a7c2abf7ced0a85d692e442799i0
- 703e5f7c49d82aab99e605af306b9a30e991e57d42f982908a962a81ac439832i0
index: /var/lib/ord/index.redb
index_cache_size: 1000000000
index_runes: true
index_sats: true
index_spent_sats: true
index_transactions: true
integration_test: true
no_index_inscriptions: true
server_password: bar
server_url: http://localhost:8888
server_username: foo

Hiding Inscription Content

Inscription content can be selectively prevented from being served by ord server.

Unlike other settings, this can only be configured with the configuration file or environment variables.

To hide inscriptions with an environment variable:

export ORD_HIDDEN='6fb976ab49dcec017f1e201e84395983204ae1a7c2abf7ced0a85d692e442799i0 703e5f7c49d82aab99e605af306b9a30e991e57d42f982908a962a81ac439832i0'

Or with the configuration file:

hidden:
- 6fb976ab49dcec017f1e201e84395983204ae1a7c2abf7ced0a85d692e442799i0
- 703e5f7c49d82aab99e605af306b9a30e991e57d42f982908a962a81ac439832i0

Teleburning

Teleburn addresses can be used to burn assets on other blockchains, leaving behind in the smoking rubble a sort of forwarding address pointing to an inscription on Bitcoin.

Teleburning an asset means something like, "I'm out. Find me on Bitcoin."

Teleburn addresses are derived from inscription IDs. They have no corresponding private key, so assets sent to a teleburn address are burned. Currently, only Ethereum teleburn addresses are supported. Pull requests adding teleburn addresses for other chains are welcome.

Ethereum

Ethereum teleburn addresses are derived by taking the first 20 bytes of the SHA-256 hash of the inscription ID, serialized as 36 bytes, with the first 32 bytes containing the transaction ID, and the last four bytes containing big-endian inscription index, and interpreting it as an Ethereum address.

예제

The ENS domain name rodarmor.eth, was teleburned to inscription zero.

The inscription ID of inscription zero is 6fb976ab49dcec017f1e201e84395983204ae1a7c2abf7ced0a85d692e442799i0.

Passing 6fb976ab49dcec017f1e201e84395983204ae1a7c2abf7ced0a85d692e442799i0 to the teleburn command:

$ ord teleburn 6fb976ab49dcec017f1e201e84395983204ae1a7c2abf7ced0a85d692e442799i0

Returns:

{
  "ethereum": "0xe43A06530BdF8A4e067581f48Fae3b535559dA9e"
}

Indicating that 0xe43A06530BdF8A4e067581f48Fae3b535559dA9e is the Ethereum teleburn address for inscription zero, which is, indeed, the current owner, on Ethereum, of rodarmor.eth.

테스팅

Test Environment

ord env <DIRECTORY> creates a test environment in <DIRECTORY>, spins up bitcoind and ord server instances, prints example commands for interacting with the test bitcoind and ord server instances, waits for CTRL-C, and then shuts down bitcoind and ord server.

ord env tries to use port 9000 for bitcoind's RPC interface, and port 9001 for ord's RPC interface, but will fall back to random unused ports.

Inside of the env directory, ord env will write bitcoind's configuration to bitcoin.conf, ord's configuration to ord.yaml, and the env configuration to env.json.

env.json contains the commands needed to invoke bitcoin-cli and ord wallet, as well as the ports bitcoind and ord server are listening on.

These can be extracted into shell commands using jq:

bitcoin=`jq -r '.bitcoin_cli_command | join(" ")' env/env.json`
$bitcoin listunspent

ord=`jq -r '.ord_wallet_command | join(" ")' env/env.json`
$ord outputs

If ord is in the $PATH and the env directory is env, the bitcoin-cli command will be:

bitcoin-cli -datadir=env`

And the ord will be:

ord --datadir env

Test Networks

Ord는 다음 플래그를 사용하여 테스트 네트워크를 지정하여 테스트할 수 있다. 테스트를 위한 Bitcoin Core 실행에 대한 자세한 내용은 비트코인 개발자 문서를 참조하자.

Most ord commands in wallet and explorer can be run with the following network flags:

네트워크플래그
Testnet--testnet 또는 -t
Signet--signet 또는 -s
Regtest--regtest 또는 -r

Regtest doesn't require downloading the blockchain since you create your own private blockchain, so indexing ord is almost instantaneous.

예제

Run bitcoind in regtest with:

bitcoind -regtest -txindex

Run ord server in regtest with:

ord --regtest server

다음을 사용해 regtest에 지갑을 만든다:

ord --regtest wallet create

다음을 사용해 regtest 수신 주소를 얻는다:

ord --regtest wallet receive

다음을 사용해 101 블록을 채굴한다(코인베이스 잠금 해제를 위해):

bitcoin-cli -regtest generatetoaddress 101 <receive address>

다음을 사용해 regtest에 인스립션을 새긴다:

ord --regtest wallet inscribe --fee-rate 1 --file <file>

다음을 사용해 인스크립션을 채굴한다:

bitcoin-cli -regtest generatetoaddress 1 <receive address>

By default, browsers don't support compression over HTTP. To test compressed content over HTTP, use the --decompress flag:

ord --regtest server --decompress

리커젼 테스트

리커젼을 테스트할 때는 종속성을 먼저 새긴다 (예: p5.js를 사용):

ord --regtest wallet inscribe --fee-rate 1 --file p5.js

This will return the inscription ID of the dependency which you can then reference in your inscription.

However, inscription IDs differ between mainnet and test chains, so you must change the inscription IDs in your inscription to the mainnet inscription IDs of your dependencies before making the final inscription on mainnet.

그런 다음을 사용해 리커젼 인스크립션을 새길 수 있다:

ord --regtest wallet inscribe --fee-rate 1 --file recursive-inscription.html

마지막으로 블록을 어느 정도 채굴해야 하고 서버를 시작해야 한다:

bitcoin-cli generatetoaddress 6 <receive address>

Mainnet Dependencies

To avoid having to change dependency inscription IDs to mainnet inscription IDs, you may utilize a content proxy when testing. ord server accepts a --content-proxy option, which takes the URL of a another ord server instance. When making a request to /content/<INSCRIPTION_ID> when a content proxy is set and the inscription is not found, ord server will forward the request to the content proxy. This allows you to run a test ord server instance with a mainnet content proxy. You can then use mainnet inscription IDs in your test inscription, which will then return the content of the mainnet inscriptions.

ord --regtest server --content-proxy https://ordinals.com

오디널 현상금 사냥 힌트

  • ord 지갑은 특정 사토시를 주고받을 수 있다. 또한 오디널 이론은 매우 간단하다. 영리한 해커라면 짧은 시간에 오디널 이론을 사용하여 사토시를 조작하는 코드를 처음부터 작성할 수 있을 것이다.

  • 오디널 이론에 대한 자세한 내용은 자주 묻는 질문에서 개요를, BIP에서 기술적 세부 사항을, ord repo에서 ord 지갑 및 블록 탐색기를 확인하길 바란다.

  • 사토시는 오디널 이론의 최초 개발자였다. 하지만 다른 사람들이 이 이론을 이단적이고 위험하다고 생각할 것을 알았기 때문에 자신의 지식을 숨겼고, 이는 결국 시간의 모래 속으로 사라져 버렸다. 이 강력한 이론은 이제야 재발견되고 있다. 당신이 희귀한 사토시를 연구하면 이에 도움이 될 수 있다.

행운과 성공을 빈다!

오디널 현상금 0

기준

서수가 0으로 끝나는 SAT를 제출 주소로 보낸다:

✅: 1857578125803250

❌: 1857578125803251

해당 SAT는 전송하는 출력(output)의 첫 번째 SAT여야 한다.

보상

100,000 SAT

제출 주소

1PE7u4wbDP2RqfKN6geD1bG57v9Gj9FXm3

상태

@count_null이 획득했다!

오디널 현상금 1

기준

제출된 모든 UTXO 중에서 가장 오래된 SAT가 포함된, 즉 가장 낮은 숫자의 SAT를 제출한 트랜잭션이 승자로 판단된다.

현상금은 난이도 조정 기간 374의 첫 번째 블록인 753984 블록까지 제출할 수 있다. 블록 753984 이후에 포함된 제출물은 고려되지 않는다.

보상

200,000 SAT

제출 주소

145Z7PFHyVrwiMWwEcUmDgFbmUbQSU9aap

상태

@ordinalsindex가 획득했다!

오디널 현상금 2

기준

제출 주소로 uncommonSAT를 보낸다:✅: 347100000000000

❌: 6685000001337

제출하기 전에 제출 주소에 트랜잭션이 수신되지 않았는지 확인하자. 첫 번째 성공적인 제출에 대해서만 보상이 지급된다.

보상

300,000 SAT

제출 주소

1Hyr94uypwWq5CQffaXHvwUMEyBPp3TUZH

상태

@utxoset가 획득했다!

오디널 현상금 3

기준

오디널 현상금 3은 두 부분으로 나뉘며, 두 부분 모두 오디널 이름 을 기반으로 한다. 오디널 이름은 서수의 수정된 base26 인코딩이다. 사용할 수 없는 제네시스 블록 코인베이스 보상 안에 짧은 이름이 고정되는 것을 방지하기 위해 서수가 길어질수록 오디널 이름은 짧아진다. 첫 번째 채굴되는 SAT 0의 이름은 nvtdijuwxlp이고, 마지막 채굴되는 SAT 2,099,999,997,689,999의 이름은 a이다.

The bounty is open for submissions until block 840000—the first block after the fourth halving. Submissions included in block 840000 or later will not be considered.

두 부분 모두 frequency.tsv를 사용한다. 이는 Google Books Ngram dataset에 있는 단어 목록 그리고 각 단어가 이 데이터셋에서 등장하는 횟수며 제출 기간이 끝날 때까지 채굴될, 전체목록에 최소 5000번 이상 등장하는 SAT의 이름만 포함하도록 필터링하였다.

frequency.tsv는 탭으로 구분된 값의 파일이다. 첫 번째 열은 단어이고 두 번째 열은 이 단어가 전체목록에 나타나는 횟수이다. 항목은 가장 적게 나타나는 항목부터 가장 많이 나타나는 항목까지 정렬된다.

이 프로그램을 사용하여 frequency.tsv를 컴파일했다.

frequency.tsv에 이름이 있는 SAT을 ord 지갑에서 검색하려면 다음 ord 명령을 사용한다:

ord wallet sats --tsv frequency.tsv

이 명령에는 SAT 인덱스가 필요하므로 인덱스를 처음 생성할 때 --index-sats를 ord에 전달해야 한다.

파트 0

희귀 SAT는 희귀 단어와 가장 잘 어울린다.

frequency.tsv에서 가장 적은 횟수로 나타나는 SAT 이름을 포함하는 UTXO를 제출한 트랜잭션이 파트 0의 승자가 된다.

파트 1

인기는 가치의 글꼴이다.

frequency.tsv에서 가장 많은 횟수로 나타나는 SAT 이름이 포함된 UTXO를 제출한 트랜잭션이 파트 1의 승자가 된다.

타이 브레이킹

동점인 경우, 즉 제출물의 빈도가 동일할 경우 먼저 제출된 것이 승자가 된다.

보상

  • 파트 0: 200,000 SAT
  • 파트 1: 200,000 SAT
  • 총: 400,000 SAT

제출 주소

17m5rvMpi78zG8RUpCRd6NWWMJtWmu65kg

상태

미수령!