WEB3DEV

Cover image for Como cunhar um NFT na Rede de Teste da Cardano usando a linha de comando
Banana Labs
Banana Labs

Posted on

Como cunhar um NFT na Rede de Teste da Cardano usando a linha de comando

Por que fazer isso?

Você tem um ativo digital que prevê que outras pessoas vão querer comprar. Pode ser único onde cada ativo tem seu próprio número de série digital (o que significa que não é fungível e pode ser representado por um NFT), ou um ativo onde cada um deles tem o mesmo valor (semelhante a moedas físicas como nickles/dimes/quarters ) e pode ser representado por um ativo nativo.

Alternativas a este método

Este artigo mostra como criar um NFT usando a linha de comando. É o método que lhe dá controle completo (nível baixo) sobre cada pequeno detalhe do início ao fim. Isso é bom se você precisar desse nível de controle ou se estiver tentando aprender como tudo se encaixa do zero para que possa entender e apreciar a tecnologia. Mas envolve baixar uma cópia da blockchain completa e mantê-la atualizada.

Uma alternativa é usar a NamiWallet, que pode ser feita a partir do seu navegador da web. Mas no momento, é muito limitada em recursos. Você só pode especificar o nome, quantidade, autor e fazer upload de uma foto. Você não tem controle sobre os metadados.

Criar um Nó Cardano

Método 1: Carteira Daedalus

Se você estiver usando um sistema operacional que possui um ambiente de desktop completo como Windows ou Mac (em oposição a um que é apenas linha de comando), você pode instalar a Carteira Daedalus para a Rede Principal da Cardano e/ou para a Rede de Teste da Cardano. Ela fará o download de toda a blockchain.

A Carteira Daedalus vem com cardano-cli e cardano-wallet que usaremos ao longo deste guia. Você precisará criar uma variável de ambiente para que isso funcione.

Método 2: Nó Cardano

Se você estiver usando um sistema operacional que possui apenas uma linha de comando/shell como o Ubuntu Server, consulte este guia: Como criar um nó Cardano na Rede de Teste no Linux

No meu caso, uso a Carteira Daedalus no Windows para a rede principal e o Ubuntu Server 20.04 LTS dentro de uma máquina virtual para a rede de teste. Isso mantém meu ambiente de teste isolado do meu ambiente de produção (Rede Principal), prevenindo acidentes.

Inicie o Nó Cardano e a Carteira

Método 1: Carteira Daedalus

Abra a Carteira Daedalus, espere até que ela sincronize 100% com a blockchain e mantenha-a em execução. Como lembrete, você precisará criar uma variável de ambiente para que isso funcione.

Abra um terminal/shell ou prompt de comando e navegue até a pasta Daedalus Wallet.

Método 2: Nó Cardano

OBSERVAÇÃO: Se você acabou de terminar o guia Como criar um nó Cardano na Rede de Teste no Linux e já tem o Nó Cardano e a Carteira Cardano em execução, você pode pular esta etapa.

Abra três shells. Isso pode ser três prompts de comando (se estiver usando Windows) ou três janelas/shells de terminal (se estiver usando Linux ou Mac).

No primeiro shell, inicie o Cardano Node. Isso é o que mantém sua cópia local da blockchain na Rede de Teste atualizada.

cardano-node run \
--topology ~/cardano/configuration/testnet/testnet-topology.json \
--database-path ~/cardano/testnet-db \
--socket-path ~/cardano/testnet-db/node.socket \
--host-addr 127.0.0.1 \
--port 3001 \
--config ~/cardano/configuration/testnet/testnet-config.json
Enter fullscreen mode Exit fullscreen mode

No segundo shell, inicie o servidor Cardano Wallet. Isso é o que permite que você interaja com o nó.

cardano-wallet serve \
--port 8090 \
--database ~/cardano/testnet-db \
--node-socket $CARDANO_NODE_SOCKET_PATH \
--testnet ~/cardano/configuration/testnet/testnet-byron-genesis.json
Enter fullscreen mode Exit fullscreen mode

Você usará o terceiro shell para todo o resto daqui para frente. Mantenha os dois shells acima abertos.

Crie uma pasta para guardar tudo

Vamos armazenar nossas chaves e metadados em uma nova pasta para manter as coisas organizadas. Nosso NFT será nomeado TestNFT1234.

mkdir -p ~/cardano/nft/TestNFT1234/policy
cd ~/cardano/nft/TestNFT1234
Enter fullscreen mode Exit fullscreen mode

Crie o ativo digital que o NFT representa

Em algum momento no futuro, os NFTs serão mais do que apenas uma foto de algo. Por enquanto, isso normalmente é uma imagem. Por exemplo:

https://ipfs.io/ipfs/QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw

Coloque seu recurso NFT (a imagem ou o que for) no IPFS. Veja este guia: Types of IPFS links and when to use them e How to Use IPFS: The Backbone of Web3.

Neste exemplo, estamos usando a imagem já enviada pela pessoa que escreveu o guia oficial do Cardano NFT:

ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw (veja a imagem em ipfs.io.)

Gere as chaves de pagamento

Execute isto. Nunca compartilhe o conteúdo desses dois arquivos com ninguém.

cardano-cli address key-gen \
--verification-key-file payment.vkey \
--signing-key-file payment.skey
Enter fullscreen mode Exit fullscreen mode

Gerar um endereço das chaves de pagamento

Execute isso para gerar o endereço e gravá-lo em um arquivo chamado payment.addr. Neste exemplo, meu endereço de pagamento acaba sendo addr_test1vzcwn6u3fephqacec4g6fr9gpsp9znpr5hsk9ggcfarn23sthac04.

cardano-cli address build \
--payment-verification-key-file payment.vkey \
--out-file payment.addr \
--testnet-magic 1097911063
Enter fullscreen mode Exit fullscreen mode

Para facilitar as coisas, vamos armazenar o endereço em uma variável. Quando executamos comandos mais tarde, podemos dizer $payment_address em vez de digitar/colar o endereço inteiro.

payment_address=$(cat payment.addr)
Enter fullscreen mode Exit fullscreen mode

Quando você vê --testnet-magic 1097911063, significa que estamos interagindo com a Rede de Teste em vez da Rede Principal (que usa --mainnet sem nenhum número). Por que é 1097911063? É o identificador de rede da Rede de Teste.

Financie o endereço

Você deve ter pelo menos 2 ADA em seu endereço de pagamento acima para cunhar um token. Se você estivesse na Rede Principal, transferiria alguns fundos para esse endereço de sua carteira ou de uma corretora.

Como estamos na Testnet, podemos usar o faucet para financiar essa conta. Solicite tokens de teste usando o faucet da ADA para obter imediatamente 1.000 tAda (teste ADA). Envie para o endereço de pagamento que você acabou de criar.

Veja quanto lovelace está em nossa conta (1.000.000 lovelace = 1 ADA).

cardano-cli query utxo \
--address $payment_address \
--testnet-magic 1097911063
Enter fullscreen mode Exit fullscreen mode

Aqui está o que pode aparecer:

TxHash                                                            TxIx        Amount
--------------------------------------------------------------------------------------
0ba233973412b629d8d1bcf6cf219a83c7cf16b59f84c1f2c488d80c5d0404dd     0        1000000000 lovelace + TxOutDatumNone
Enter fullscreen mode Exit fullscreen mode

Exportar parâmetros de protocolo

Precisamos de parâmetros de protocolo atuais para quando calcularmos transações.

cardano-cli query protocol-parameters \
--testnet-magic 1097911063 \
--out-file protocol.json
Enter fullscreen mode Exit fullscreen mode

Isso gera um arquivo de 10 KB chamado protocol.json que contém informações como esta:

{
    "txFeePerByte": 44,
    "minUTxOValue": null,
    "decentralization": 0,
    "utxoCostPerWord": 34482,
    "stakePoolDeposit": 500000000,
    "poolRetireMaxEpoch": 18,
    "extraPraosEntropy": null,
    "collateralPercentage": 150,
    "stakePoolTargetNum": 500,
    "maxBlockBodySize": 73728,
    "minPoolCost": 340000000,
    "maxTxSize": 16384,
    "treasuryCut": 0.2,
    "maxBlockExecutionUnits": {
        "memory": 50000000,
        "steps": 40000000000
    },
    "maxCollateralInputs": 3,
    "maxValueSize": 5000,
    "maxBlockHeaderSize": 1100,
    "maxTxExecutionUnits": {
        "memory": 12500000,
        "steps": 10000000000
    },
    "costModels": {
        "PlutusScriptV1": {
            "cekConstCost-exBudgetMemory": 100,
            "unBData-cpu-arguments": 150000,
            "divideInteger-memory-arguments-minimum": 1,
            "nullList-cpu-arguments": 150000,
            "cekDelayCost-exBudgetMemory": 100,
            ...
        }
    },
    "protocolVersion": {
        "minor": 0,
        "major": 6
    },
    "txFeeFixed": 155381,
    "stakeAddressDeposit": 2000000,
    "monetaryExpansion": 3.0e-3,
    "poolPledgeInfluence": 0.3,
    "executionUnitPrices": {
        "priceSteps": 7.21e-5,
        "priceMemory": 5.77e-2
    }
}
Enter fullscreen mode Exit fullscreen mode

Gere as chaves de política

Rode isto. Nunca compartilhe o conteúdo desses dois arquivos com ninguém.

cardano-cli address key-gen \
--verification-key-file policy/policy.vkey \
--signing-key-file policy/policy.skey
Enter fullscreen mode Exit fullscreen mode

Gere o Script de Política

Execute o seguinte para gerar o arquivo policy.script.

echo "{" >> policy/policy.script
echo "  \"type\": \"all\"," >> policy/policy.script
echo "  \"scripts\":" >> policy/policy.script
echo "  [" >> policy/policy.script
echo "   {" >> policy/policy.script
echo "     \"type\": \"sig\"," >> policy/policy.script
echo "     \"keyHash\": \"$(cardano-cli address key-hash --payment-verification-key-file policy/policy.vkey)\"" >> policy/policy.script
echo "   }" >> policy/policy.script
echo "  ]" >> policy/policy.script
echo "}" >> policy/policy.script
Enter fullscreen mode Exit fullscreen mode

Vai parecer algo assim:

{
  "type": "all",
  "scripts":
  [
   {
     "type": "sig",
     "keyHash": "6d1321490cde0b447794edff9239cf0668ae01f0df33823d0a3bbcf7"
   }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Armazene o nome do arquivo de script em uma variável.

script="policy/policy.script"
Enter fullscreen mode Exit fullscreen mode

Gerar o PolicyID

Execute isso para gerar o hash PolicyID exclusivo usando o script de política.

cardano-cli transaction policyid \
--script-file ./policy/policy.script >> policy/policyID
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, o PolicyID é 155f313f864d009d7b0b519b1295c9fab7b75c17cfc5ba1aed501b7c.

Armazene o PolicyID em uma variável.

policyid=$(cat policy/policyID)
Enter fullscreen mode Exit fullscreen mode

Codifique o nome do NFT em base-16

Codifique o nome do seu NFT usando base-16 (hexadecimal). Você pode usar esta ferramenta online para fazer isso ou usar o seguinte comando no Linux.

echo -n "TestNFT1234" | xxd -ps
Enter fullscreen mode Exit fullscreen mode

Armazene isso em uma variável. Estamos criando apenas um NFT neste exemplo para que a variável Token Amount seja definida de acordo.

tokenname="546573744e465431323334"
tokenamount=1
Enter fullscreen mode Exit fullscreen mode

Crie os metadados

Crie os metadados para sua NFT. Consulte https://github.com/cardano-foundation/CIPs/tree/master/CIP-0025 para obter a estrutura mais recente.

Salve-o como metadata.json.

nano metadata.json
Enter fullscreen mode Exit fullscreen mode

No exemplo a seguir:

  • 155f313f864d009d7b0b519b1295c9fab7b75c17cfc5ba1aed501b7c é o PolicyID
  • 546573744e465431323334 é o nome do ativo (TestNFT1234) codificado em base 16 (hexadecimal)
  • 721 é a chave que a comunidade está usando para significar que isso é um NFT
{
    "721": {
        "155f313f864d009d7b0b519b1295c9fab7b75c17cfc5ba1aed501b7c": {
            "546573744e465431323334": {
                "name": "TestNFT1234",
                "image": [ "https://ipfs.io/ipfs/", "QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw" ],
                "mediaType": "image/png",
                "description": "Just another fun NFT"
            }
        },
    "version": "1.0"
    }
}
Enter fullscreen mode Exit fullscreen mode

Se não dividissemos o atributo "image" em um array, teríamos recebido este erro:

Command failed: transaction build Error: Error reading metadata at: "metadata.json" Value out of range within the metadata item 721: [contents of metadata.json here] Text string metadata value must consist of at most 64 UTF8 bytes, but it consists of 67 bytes.

Reúna as informações necessárias para construir a transação

Execute isso.

cardano-cli query utxo \
--address $payment_address \
--testnet-magic 1097911063
Enter fullscreen mode Exit fullscreen mode

Armazene o valor de TxHash e TxIx em variáveis.

txhash="0ba233973412b629d8d1bcf6cf219a83c7cf16b59f84c1f2c488d80c5d0404dd"
txix="0"
Enter fullscreen mode Exit fullscreen mode

Obter o endereço do destinatário

Determine quem será o primeiro destinatário deste NFT. Pode ser sua própria carteira pessoal. Seja qual for o caso, obtenha o endereço da carteira dessa pessoa.

first_nft_owner_address="addr_test1qqwtrpkkh8a60pjjljn6n90mzdf6fa9wempj8s6t732xh4deudejw0dvq2hyrty7htt02xepkuq65w0peun9wx5kxpuskcgwl9"
Enter fullscreen mode Exit fullscreen mode

Estime a taxa e o alvo do slot

Ainda não sabemos quanto Lovelace isso vai custar. Comece com 1400000 lovelace (1,4 ADA), que é o requisito mínimo de UTxO. Se acabar custando mais porque os metadados são muito grandes, seremos forçados a ajustar mais tarde.

fee=1400000
Enter fullscreen mode Exit fullscreen mode

Verifique se todas as variáveis estão definidas

Execute o seguinte e observe a saída. Certifique-se de que tudo tem um valor.

echo [payment_address] NFT will be generated by payment address \"$payment_address\"
echo [first_nft_owner_address] NFT will be sent to address \"$first_nft_owner_address\"
echo [fee] This is estimated to cost \"$fee\" lovelace
echo [policyid] The PolicyID is \"$policyid\"
echo [tokenname] The token name in hexadecimal is \"$tokenname\"
echo [tokenamount] We are going to mint \"$tokenamount\" tokens
echo [script] The policy script is \"$script\"
echo [txhash][txix] This transaction will be funded by TxHash \"$txhash\" using TxIx \"$txix\"
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, aqui está a saída (com os comandos removidos para facilitar a leitura):

[payment_address] NFT will be generated by payment address "addr_test1vzcwn6u3fephqacec4g6fr9gpsp9znpr5hsk9ggcfarn23sthac04"
[first_nft_owner_address] NFT will be sent to address "addr_test1qqwtrpkkh8a60pjjljn6n90mzdf6fa9wempj8s6t732xh4deudejw0dvq2hyrty7htt02xepkuq65w0peun9wx5kxpuskcgwl9"
[fee] This is estimated to cost "1400000" lovelace
[policyid] The PolicyID is "155f313f864d009d7b0b519b1295c9fab7b75c17cfc5ba1aed501b7c"
[tokenname] The token name in hexadecimal is "546573744e465431323334"
[tokenamount] We are going to mint "1" tokens
[script] The policy script is "policy/policy.script"
[txhash][txix] This transaction will be funded by TxHash "0ba233973412b629d8d1bcf6cf219a83c7cf16b59f84c1f2c488d80c5d0404dd" using TxIx "0"
Enter fullscreen mode Exit fullscreen mode

Construir a transação

Agora vamos construir a transação e armazená-la dentro de um arquivo chamado matx.raw.

cardano-cli transaction build \
--testnet-magic 1097911063 \
--alonzo-era \
--tx-in $txhash#$txix \
--tx-out $first_nft_owner_address+$fee+"$tokenamount $policyid.$tokenname" \
--change-address $payment_address \
--mint="$tokenamount $policyid.$tokenname" \
--minting-script-file $script --metadata-json-file metadata.json \
--witness-override 2
--out-file matx.raw
Enter fullscreen mode Exit fullscreen mode

IMPORTANTE: Se você definir o valor --change-address para $first_nft_owner_address, todo o saldo ADA de sua carteira de pagamentos será enviado para esse endereço. Se você é o proprietário dele, então isso não é um problema.

Por exemplo, suponha que $first_nft_owner_address seja sua carteira principal e você transferiu 10 ADA de $first_nft_owner_address para $payment_address para cunhar um NFT. A cunhagem do NFT pode realmente custar 1,590889 ADA. Se você quiser devolver os 8.6 ADA restantes para sua carteira principal, defina --change-address como $first_nft_owner_address. Mas se você quiser cunhar outro NFT e manter o 8.6 ADA nessa carteira temporária, defina-o como $payment_address.

Se você receber uma mensagem dizendo algo como Minimum required UTxO: Lovelace 1448244 altere a taxa para esse valor. Caso contrário, continue sem fazer nenhuma alteração. Neste exemplo, ele diz Estimated transaction fee: Lovelace 190889, então estamos todos bem.

fee=1448244 # Run this only if you got the above warning
Enter fullscreen mode Exit fullscreen mode

Se você receber uma mensagem informando que não tem fundos suficientes para cobrir o custo da transação, poderá especificar uma segunda entrada --tx-in. Por exemplo, quando executamos a consulta pela cardano-cli utxo --address $address --testnet-magic 1097911063, ele mostra o seguinte. Ao especificar uma segunda entrada --tx-in, ela pode combinar os fundos.

TxHash                                 TxIx        Amount
--------------------------------------------------------------------------------------
0ba233973412b629d8d1bcf6cf219a83c7cf16b59f84c1f2c488d80c5d0404dd     0        50000000 lovelace + TxOutDatumNone
77300dc0598bdc8268a706705ee7521f76bf29cdd9d0c7580b69c660f0f38bec     0        48220906 lovelace + TxOutDatumNone
Enter fullscreen mode Exit fullscreen mode

Para os curiosos, o arquivo fica assim:

{
    "type": "TxBodyAlonzo",
    "description": "",
    "cborHex": "86a700818258200ba233973412b629d8d1bcf6cf219a83c7cf16b59f84c1f
    2c488d80c5d0404dd000d800182825839001cb186d6b9fba78652fca7a995fb1353a4f4ae
    cec323c34bf4546bd5b9e373273dac02ae41ac9ebad6f51b21b701aa39e1cf26571a96307
    91a3b828397825839001cb186d6b9fba78652fca7a995fb1353a4f4aecec323c34bf4546b
    d5b9e373273dac02ae41ac9ebad6f51b21b701aa39e1cf26571a963079821a00155cc0a15
    81c155f313f864d009d7b0b519b1295c9fab7b75c17cfc5ba1aed501b7ca14b546573744e
    46543132333401021a0002e9a90e8009a1581c155f313f864d009d7b0b519b1295c9fab7b
    75c17cfc5ba1aed501b7ca14b546573744e465431323334010758206a46c80316d784a2b4
    936540adca437283d949a52878616b9494eb60279878779f82008201818200581c6d13214
    90cde0b447794edff9239cf0668ae01f0df33823d0a3bbcf7ff8080f5d90103a100a11902
    d1a2783831353566333133663836346430303964376230623531396231323935633966616
    23762373563313763666335626131616564353031623763a1763534363537333734346534
    3635343331333233333334a46b6465736372697074696f6e744a75737420616e6f7468657
    22066756e204e465465696d616765827568747470733a2f2f697066732e696f2f69706673
    2f782e516d5268545462557250594577336d4a4747685171515354396b383676314450426
    95454574a474b444a73564677696d656469615479706569696d6167652f706e67646e616d
    656b546573744e4654313233346776657273696f6e63312e30"
}
Enter fullscreen mode Exit fullscreen mode

Para ver o que isso diz:

  • Acesse cbor.me
  • Cole o valor de cborHex na caixa à direita
  • Marque as quatro caixas de seleção acima dessa caixa (como texto, utf8, emb cbor, cborseq)
  • Clique na seta verde ← ao lado da palavra "Bytes"

A caixa da esquerda agora conterá algo assim:

[{0: [[h'0BA233973412B629D8D1BCF6CF219A83C7CF16B59F84C1F2C488D80C5D0404DD', 0]],
13: [], 1: [[h'001CB186D6B9FBA78652FCA7A995FB1353A4F4AECEC323C34BF4546BD5B9E3732
73DAC02AE41AC9EBAD6F51B21B701AA39E1CF26571A963079', 998409111], [h'001CB186D6B9F
BA78652FCA7A995FB1353A4F4AECEC323C34BF4546BD5B9E373273DAC02AE41AC9EBAD6F51B21B70
1AA39E1CF26571A963079', [1400000, {h'155F313F864D009D7B0B519B1295C9FAB7B75C17CFC
5BA1AED501B7C': {'TestNFT1234': 1}}]]], 2: 190889, 14: [], 9: {h'155F313F864D009
D7B0B519B1295C9FAB7B75C17CFC5BA1AED501B7C': {'TestNFT1234': 1}}, 7: h'6A46C80316
D784A2B4936540ADCA437283D949A52878616B9494EB6027987877'}, [[0, [1, [[0, h'6D1321
490CDE0B447794EDFF9239CF0668AE01F0DF33823D0A3BBCF7']]]]], [], [], true, 259({0:
{721: {"155f313f864d009d7b0b519b1295c9fab7b75c17cfc5ba1aed501b7c": {"546573744e4
65431323334": {"description": "Just another fun NFT", "image": ["https://ipfs.io
/ipfs/", "QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw"], "mediaType": "image/
png", "name": "TestNFT1234"}}, "version": "1.0"}}})]
Enter fullscreen mode Exit fullscreen mode

É óbvio o que tudo isso significa, então não vou me dar ao trabalho de explicar. 🙃 Você pode ver o código-fonte do Cbor.hs se estiver interessado em entrar nessa toca de coelho.

Assine a transação

Para provar que autorizamos esta transação, devemos assiná-la usando a chave de pagamento e a chave de política que geramos anteriormente. Lembre-se, nunca compartilhe essas chaves com ninguém.

cardano-cli transaction sign \
--signing-key-file payment.skey \
--signing-key-file policy/policy.skey \
--testnet-magic 1097911063 \
--tx-body-file matx.raw \
--out-file matx.signed
Enter fullscreen mode Exit fullscreen mode

Envie a transação para a blockchain

Até este ponto, apenas lemos da blockchain Cardano Testnet. Mas uma vez que executamos o comando abaixo, estamos gravando na blockchain. Não há volta.

cardano-cli transaction submit \
--tx-file matx.signed \
--testnet-magic 1097911063
Enter fullscreen mode Exit fullscreen mode

Você deve ver a mensagem:

Transaction successfully submitted.

Confirme se funcionou

Vá para https://testnet.cardanoscan.io e procure o endereço da carteira (aquele armazenado em $first_nft_owner_address). Use a lista suspensa para visualizar os tokens.

Se ainda não estiver visível, aguarde 10 a 30 segundos e verifique novamente.

Retorne o teste ADA para o faucet

Se já estiver tudo concluído, é recomendável que você devolva qualquer tAda restante para a torneira.

Faça isso na Rede Principal

Se tudo funcionou como você esperava, agora você pode fazer isso na Rede Principal. Substitua --testnet-magic 1097911063 por --mainnet em todos os comandos deste guia.


Esse artigo é uma tradução de Christopher Huxley feita por @bananlabs. Você pode encontrar o artigo original aqui

Top comments (0)