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:
-
Encontrar o primeiro output da transação cujo script pubkey começa por
OP_RETURN OP_13
. -
Concatenar todos os dados seguintes num buffer de carga útil.
-
Descodificar uma sequência de números inteiros LEB128 de 128 bits a partir do buffer de carga útil.
-
Analisar a sequência de números inteiros numa mensagem não escrita. (untyped).
-
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:
bloco | TX | quantidade | output |
---|---|---|---|
10 | 5 | 5 | 1 |
50 | 1 | 25 | 4 |
10 | 7 | 1 | 8 |
10 | 5 | 10 | 3 |
Em primeiro lugar, são ordenados pela altura do bloco e pelo índice da transação:
bloco | TX | quantidade | output |
---|---|---|---|
10 | 5 | 5 | 1 |
10 | 5 | 10 | 3 |
10 | 7 | 1 | 8 |
50 | 1 | 25 | 4 |
E depois codificado em delta como:
Bloco Delta | TX delta | quantidade | output |
---|---|---|---|
10 | 5 | 5 | 1 |
0 | 0 | 10 | 3 |
0 | 2 | 1 | 8 |
40 | 1 | 25 | 4 |
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:
Divisibilidade | Visualização |
---|---|
0 | 1234 |
1 | 123.4 |
2 | 12.34 |
3 | 1.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çadores | Visualização |
---|---|
0b1 | A•AAA |
0b11 | A•A•AA |
0b10 | AA•AA |
0b111 | A•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:
Nome | Codificação |
---|---|
A | 0 |
B | 1 |
… | … |
Y | 24 |
Z | 25 |
AA | 26 |
AB | 27 |
… | … |
AY | 50 |
AZ | 51 |
BA | 52 |
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.