As Runes não têm uma Especificação

ord é a implementação de referência das Runes e constitui a especificação normativa do protocolo de Runes.

Nada do que ler aqui ou noutro lugar, para além do código ord, é uma especificação. Esta descrição em prosa do protocolo runes é fornecida como um guia para o comportamento do ord, e o código do próprio ord deve ser sempre consultado para confirmar a exatidão de qualquer descrição em prosa do mesmo.

Se, devido a um bug no ord, este documento divergir do comportamento real do ord e for impraticável alterar o comportamento do ord, este documento será corrigido para concordar com o comportamento real do ord.

Os utilizadores de implementações alternativas fazem-no por sua responsabilidade e risco, e os serviços que desejem integrar Runes são fortemente encorajados a usar o próprio ord para fazer transações de Runes, e para determinar o estado das runes, mints e saldos.

Pedras Rúnicas (Runestones)

As mensagens do protocolo Rune são designadas por "runestones".

O protocolo das Runes foi ativado no bloco 840.000. As runestones de blocos anteriores são ignoradas.

Em termos abstractos, as runestones contêm os seguintes campos:

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

As runes são criadas por gravuras (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>,
}
}

Que podem conter termos de mintar:

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

As runes são transferidas por éditos (edict):

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

Os IDs das runes são codificadas como a altura do bloco e o índice de transação da transação em que a rune foi gravada:

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

Os IDs das runes são representados em texto como BLOCK:TX.

Os nomes das runes são codificados como números inteiros de base-26 modificados:

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

Decifrar

As runestones são decifradas a partir das transacções com os seguintes passos:

  1. Encontrar o primeiro output da transação cujo script pubkey começa por OP_RETURN OP_13.

  2. Concatenar todos os dados seguintes num buffer de carga útil.

  3. Descodificar uma sequência de números inteiros LEB128 de 128 bits a partir do buffer de carga útil.

  4. Analisar a sequência de números inteiros numa mensagem não escrita. (untyped).

  5. Analisar a mensagem não escrita (untyped) numa runestone.

A descodificação pode produzir uma runestone malformada, designada por cenotáfio.

Localizar o output da runestone

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

Montar o buffer da carga útil (payload)

A memória intermédia da carga útil é montada concatenando os envios de dados, após OP_13, na pubkey do script correspondente.

Os data pushes são os opcodes 0 a 78, inclusive. Se for encontrado um opcode non-data push, i.e., qualquer opcode igual ou superior ao opcode 79, a runestone decifrada é um cenotáfio sem gravura, mint ou édito.

Descodificação da sequência de inteiros

Uma sequência de números inteiros de 128 bits é descodificada a partir da carga útil como varints LEB128.

Os varints LEB128 são codificados como uma sequência de bytes, cada um dos quais com o bit mais significativo definido, exceto o último.

Se uma varint LEB128 contiver mais de 18 bytes, ia ultrapassar (overflow) um u128, ou é truncada, o que significa que o fim da memória intermédia do payload é atingido antes de se encontrar um byte com o bit de continuação não definido, a runestone descodificada é um cenotáfio sem gravação, mints ou éditos.

Analisar a mensagem

A sequência de inteiros é analisada numa mensagem não escrita (untyped):

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

Os números inteiros são interpretados como uma sequência de pares etiqueta/valor (tag/value), com etiquetas duplicadas que acrescentam o seu valor ao valor do campo.

Se for encontrada uma etiqueta com valor zero, todos os números inteiros seguintes são interpretados como uma série de éditos de quatro números, cada um consistindo numa altura de bloco de ID de rune, índice de transação de ID de rune, montante e output.

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

As alturas dos blocos ID de rune e os índices de transação nos éditos são codificados em delta.

A descodificação do ID da rune do édito começa com uma altura de bloco de base e um índice de transação de zero. Ao descodificar cada ID de rune, primeiro o delta da altura do bloco codificado é adicionado à altura do bloco de base. Se o delta da altura do bloco for zero, o número inteiro seguinte é um delta do índice de transação. Se o delta da altura do bloco for superior a zero, o número inteiro seguinte é um índice de transação absoluto.

Isto implica que os éditos devem primeiro ser ordenados por ID de rune antes de serem codificados numa runestone.

Por exemplo, para codificar os seguintes éditos:

blocoTXquantidadeoutput
10551
501254
10718
105103

Em primeiro lugar, são ordenados pela altura do bloco e pelo índice da transação:

blocoTXquantidadeoutput
10551
105103
10718
501254

E depois codificado em delta como:

Bloco DeltaTX deltaquantidadeoutput
10551
00103
0218
401254

Se a output de um édito for superior ao número de outputs da transação, se for encontrada uma ID de rune de édito com bloco zero e índice de transação diferente de zero ou se um campo for truncado, ou seja, se for encontrada uma etiqueta sem valor, a rune descodificada é um cenotáfio.

Note-se que, se um cenotáfio for produzido aqui, o cenotáfio não está vazio, o que significa que contém os campos e os éditos, que podem incluir uma gravura e um mint.

Analisar a runestone

A runestone:

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

É analisado a partir da mensagem não assinada utilizando as seguintes etiquetas:

#![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 que as etiquetas são agrupadas por paridade, ou seja, se são pares ou ímpares. As etiquetas ímpares não reconhecidas são ignoradas. Os tags pares não reconhecidos produzem um cenotáfio.

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

Corpo (Body)

A etiqueta Body marca o fim dos campos da runestone, fazendo com que todos os números inteiros seguintes sejam interpretados como éditos.

Bandeiras (Flag)

O campo Flag contém um mapa de bits de bandeiras, cuja posição é 1 << FLAG_VALUE:

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

A marca Etching assinala esta transação como incluindo uma gravura.

O sinalizador Terms marca a gravação desta transação como tendo termos de mint abertos.

O sinalizador Turbo marca a gravação desta transação como tendo optado por futuras alterações de protocolo. Estas alterações de protocolo podem aumentar os custos de validação do cliente levemente, ou simplesmente ser muito alta.

A bandeira Cenotaph não é reconhecida.

Se o valor do campo flags após remover as flags reconhecidas for diferente de zero, a runestone é um cenotáfio.

Rune

O campo Rune contém o nome da rune que está a ser gravada. Se a bandeira Etching estiver definida mas o campo Rune for omitido, é atribuído um nome de rune reservado.

Pré-mineração

O campo Premine contém a quantidade de runes pré-mineradas.

Limite

O campo Cap contém o número permitido de mints

Quantidade

O campo Amount contém a quantidade de runes que cada transação de mint recebe.

(altura inicial) HeightStart e (altura final) HeightEnd

Os campos HeightStart e HeightEnd contêm as alturas absolutas do início e do fim do bloco do mint, respetivamente. O mint está aberto a partir do bloco com a altura HeightStart e fecha no bloco com a altura HeightEnd.

(desvio inicial) OffsetStart e (desvio final) OffsetEnd

Os campos OffsetStart e OffsetEnd contêm as alturas inicial e final do bloco do mint, relativamente ao bloco em que a gravura é extraída. o mint abre no bloco com a altura OffsetStart + ETCHING_HEIGHT, e fecha no bloco com a altura OffsetEnd + ETCHING_HEIGHT.

Mint

O campo Mint contém o ID da rune a ser mintada nesta transação.

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. If the pointer is greater than the number of outputs, the runestone is a cenotaph.

Cenotáfio

O campo do Cenotaph não é reconhecido.

Divisibilidade

O campo Divisibility, elevado à potência de dez, é o número de subunidades numa super unidade de runes.

Por exemplo, a quantidade 1234 de diferentes runes com divisibilidade de 0 a 3 é apresentada da seguinte forma:

DivisibilidadeVisualização
01234
1123.4
212.34
31.234
Espaçadores

O campo Spacers é um campo de bits de espaçadores que devem ser apresentados entre as letras do nome da rune.

O campo N do campo de bits, começando pelo menos significativo, determina se deve ou não ser apresentado um espaçador entre o N e o N+1 caráter, começando pela esquerda do nome da rune.

Por exemplo, o nome da rune AAAA é apresentado com espaçadores diferentes:

EspaçadoresVisualização
0b1A•AAA
0b11A•A•AA
0b10AA•AA
0b111A•A•A•A

Os espaçadores à direita são ignorados.

Símbolo

O campo Symbol é o ponto de código Unicode do símbolo de moeda da rune, que deve ser apresentado após os montantes dessa rune. Se uma rune não tiver um símbolo de moeda, deve ser usado o carácter genérico de moeda ¤.

Por exemplo, se o Symbol é # e a divisibilidade é 2, a quantidade de 1234 unidades deve ser apresentada como 12.34 #.

Nop

O campo Nop não é reconhecido.

Cenotáfios

Os cenotáfios têm os seguintes efeitos:

  • Todas as runes introduzidas numa transação que contenha um cenotáfio são queimadas.

  • Se a runestone que produziu o cenotáfio continha uma gravura, a rune gravada tem fornecimento zero e não pode ser mintada.

  • Se a runestone que produziu o cenotáfio for um mint, o mint conta para o limite de mints e as runes mintadas são queimadas.

Cenotáfios podem ser criados se uma runestone contiver uma tag par não reconhecida, uma flag não reconhecida, um édito com um número de saída maior que o número de entradas, um ID de rune com bloco zero e índice de transação diferente de zero, um varint mal formado, uma instrução non-datapush no script pubkey da saída da runestone, uma tag sem um valor subsequente, ou inteiros finais que não fazem parte de um édito.

Executar a runestone

As runestones são executados na ordem em que as suas transações são incluídas nos blocos.

Gravuras

Uma runestone pode conter uma gravura:

#![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 é o nome da rune a ser gravada, codificado como um número inteiro de base-26 modificado.

Os nomes das runes consistem nas letras de A a Z, com a seguinte codificação:

NomeCodificação
A0
B1
Y24
Z25
AA26
AB27
AY50
AZ51
BA52

E assim em diante.

Os nomes de runes AAAAAAAAAAAAAAAAAAAAAAAAAAA e superiores estão reservados.

Se a rune for omitida, é atribuído um nome de rune reservado da seguinte forma

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

6402364363415443603228541259936211926 corresponde ao nome da rune AAAAAAAAAAAAAAAAAAAAAAAAAAA.

Se a rune estiver presente, deve ser desbloqueada a partir do bloco em que a gravura aparece.

Inicialmente, todos os nomes de runes de comprimento igual ou superior a treze, até ao primeiro nome de rune reservado, são desbloqueados.

As runes começam a ser desbloqueadas no bloco 840.000, o bloco em que o protocolo de runes é ativado.

A partir daí, a cada período de 17.500 blocos, o próximo comprimento mais curto de nomes de runes é continuamente desbloqueado. Assim, entre o bloco 840.000 e o bloco 857.500, os nomes das runes de doze caracteres são desbloqueados, entre o bloco 857.500 e o bloco 875.000 os nomes das runes de onze caracteres são desbloqueados, e assim sucessivamente, até que os nomes das runes de um carácter sejam desbloqueados entre o bloco 1.032.500 e o bloco 1.050.000. Vê a base de código ord para saberes o calendário exato do desbloqueio.

Para evitar a execução antecipada de uma gravura que tenha sido transmitida mas não minerada, se um nome de rune não reservado estiver a ser gravado, a transação de gravura deve conter umcompromisso válido para o nome que está a ser gravado.

Um compromisso consiste num envio de dados do nome da rune, codificado como um número inteiro little-endian com o zero byte final eliminado, presente num tapscript de testemunha de entrada em que a output que está a ser gasta tem pelo menos seis confirmações.

Se não estiver presente um compromisso válido, a gravação é ignorada.

Mintar

Uma runestone pode cunhar uma rune ao incluir o ID da rune no campo Mint.

Se o mint estiver aberto, o montante do mint é adicionado às runes não atribuídas no input da transação. Estas runes podem ser transferidas através de éditos e, caso contrário, serão transferidas para o primeira output que não seja OP_RETURN ou para o output designado pelo campo Pointer.

Os mints podem ser feitos em qualquer transação após uma gravação, incluindo no mesmo bloco.

Transferência

As runes são transferidas por éditos (edict):

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

Uma rune pode conter qualquer número de éditos, que são processados em sequência.

Antes de os éditos serem processados, as runes de entrada, bem como as runes mintadas ou pré-minadas, se existirem, não são atribuídas.

Cada édito diminui o saldo não alocado da rune id e aumenta o saldo alocado aos outputs da transação da rune id.

Se um édito alocar mais runes do que as que não estão atualmente alocadas, o montante é reduzido para o número de runes atualmente não alocadas. Por outras palavras, o édito aloca todas as unidades restantes não alocadas da rune id.

Uma vez que o ID de uma rune gravada não é conhecido antes de ser incluído num bloco, o ID 0:0 é utilizado para significar a rune que está a ser gravada nesta transação, caso exista.

Um édito com amount zero aloca todas as unidades restantes da rune id.

Um édito com output igual ao número de outputs da transação atribui o amount de runes a cada output não OP_RETURN, por ordem.

Um decreto com amount zero e output igual ao número de outputs de transação divide todas as unidades não alocadas de id de rune entre cada output não-OP_RETURN. Se o número de runes não atribuídas não for divisível pelo número de outputs não OP_RETURN, é atribuída 1 rune adicional às primeiras R outputs não OP_RETURN, em que R é o resto após dividir o saldo de unidades não atribuídas de id de rune pelo número de outputs não OP_RETURN.

Se qualquer édito numa rune tiver uma ID de rune com block zero e tx superior a zero, ou um output superior ao número de outputs de transação, a rune é um cenotáfio.

Note que os éditos em cenotáfios não são processados, e todos os inputs das runes são queimados.