From 098666fc68075705f7c27af535e8bbbe452f6725 Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Fri, 11 Jun 2021 21:25:11 -0500 Subject: [PATCH 01/50] Counts the words in each chapter, ignoring code blocks and digits --- word_count.ipynb | 266 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 word_count.ipynb diff --git a/word_count.ipynb b/word_count.ipynb new file mode 100644 index 0000000..7a19a21 --- /dev/null +++ b/word_count.ipynb @@ -0,0 +1,266 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Untitled25.ipynb", + "provenance": [], + "authorship_tag": "ABX9TyOJqhnf6/YgfQMx6pfh6Fth", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kT4wyWuy2szs" + }, + "source": [ + "import numpy as np\n", + "import os\n", + "import pandas as pd" + ], + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "9J62Uh4H2Y9g", + "outputId": "f4147b98-f72a-4ad2-8b5b-c3bb9f0c86db" + }, + "source": [ + "!git clone https://github.com/icculp/Learning-Bitcoin-from-the-Command-Line.git" + ], + "execution_count": 2, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Cloning into 'Learning-Bitcoin-from-the-Command-Line'...\n", + "remote: Enumerating objects: 6634, done.\u001b[K\n", + "remote: Counting objects: 100% (238/238), done.\u001b[K\n", + "remote: Compressing objects: 100% (196/196), done.\u001b[K\n", + "remote: Total 6634 (delta 109), reused 82 (delta 42), pack-reused 6396\u001b[K\n", + "Receiving objects: 100% (6634/6634), 7.53 MiB | 13.87 MiB/s, done.\n", + "Resolving deltas: 100% (4068/4068), done.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k_g4-Fvn2yPy" + }, + "source": [ + "def count_words():\n", + " \"\"\" Counts words ignoring code blocks and digits \"\"\"\n", + " columns=['Chapter', 'Word Count']\n", + " counts = []\n", + " repo_path = '/content/Learning-Bitcoin-from-the-Command-Line/'\n", + " for chapter in os.listdir(repo_path):\n", + " if not chapter.endswith('.md'):\n", + " continue\n", + " count = 0\n", + " flag = 0 # ignores words between ``` code markdown\n", + " with open(repo_path + chapter) as ch:\n", + " for line in ch.readlines():\n", + " if flag:\n", + " if '```' in line:\n", + " flag = 0\n", + " continue\n", + " continue\n", + " if '```' in line:\n", + " flag = 1\n", + " continue\n", + " for word in line.split():\n", + " if any(ch.isdigit() for ch in word):\n", + " continue\n", + " count += 1\n", + " counts.append((chapter, count))\n", + " # print(chapter, count)\n", + " return pd.DataFrame(counts, columns=columns)" + ], + "execution_count": 35, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2-pkEaYF3Uxm" + }, + "source": [ + "chapter_word_counts = count_words()\n", + "chapter_word_counts.sort_values(by=['Chapter'], inplace=True)" + ], + "execution_count": 38, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 631 + }, + "id": "IPkG4oQJ6f1e", + "outputId": "d057cf19-4d40-477a-964c-d2b6154e1e73" + }, + "source": [ + "from google.colab import data_table\n", + "data_table.DataTable(chapter_word_counts, include_index=False)" + ], + "execution_count": 39, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.module+javascript": "\n import \"https://ssl.gstatic.com/colaboratory/data_table/a6224c040fa35dcf/data_table.js\";\n\n window.createDataTable({\n data: [[\"01_0_Introduction.md\",\n{\n 'v': 1128,\n 'f': \"1128\",\n }],\n [\"01_1_Introducing_Bitcoin.md\",\n{\n 'v': 2784,\n 'f': \"2784\",\n }],\n [\"02_0_Setting_Up_a_Bitcoin-Core_VPS.md\",\n{\n 'v': 221,\n 'f': \"221\",\n }],\n [\"02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md\",\n{\n 'v': 1937,\n 'f': \"1937\",\n }],\n [\"02_2_Setting_Up_Bitcoin_Core_Other.md\",\n{\n 'v': 245,\n 'f': \"245\",\n }],\n [\"03_0_Understanding_Your_Bitcoin_Setup.md\",\n{\n 'v': 225,\n 'f': \"225\",\n }],\n [\"03_1_Verifying_Your_Bitcoin_Setup.md\",\n{\n 'v': 801,\n 'f': \"801\",\n }],\n [\"03_2_Knowing_Your_Bitcoin_Setup.md\",\n{\n 'v': 540,\n 'f': \"540\",\n }],\n [\"03_3_Setting_Up_Your_Wallet.md\",\n{\n 'v': 1741,\n 'f': \"1741\",\n }],\n [\"03_3__Interlude_Using_Command-Line_Variables.md\",\n{\n 'v': 354,\n 'f': \"354\",\n }],\n [\"03_4_Receiving_a_Transaction.md\",\n{\n 'v': 1521,\n 'f': \"1521\",\n }],\n [\"03_5_Understanding_the_Descriptor.md\",\n{\n 'v': 1393,\n 'f': \"1393\",\n }],\n [\"04_0_Sending_Bitcoin_Transactions.md\",\n{\n 'v': 153,\n 'f': \"153\",\n }],\n [\"04_1_Sending_Coins_The_Easy_Way.md\",\n{\n 'v': 1087,\n 'f': \"1087\",\n }],\n [\"04_2_Creating_a_Raw_Transaction.md\",\n{\n 'v': 1840,\n 'f': \"1840\",\n }],\n [\"04_2__Interlude_Using_JQ.md\",\n{\n 'v': 2034,\n 'f': \"2034\",\n }],\n [\"04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md\",\n{\n 'v': 428,\n 'f': \"428\",\n }],\n [\"04_4_Sending_Coins_with_a_Raw_Transaction.md\",\n{\n 'v': 1011,\n 'f': \"1011\",\n }],\n [\"04_4__Interlude_Using_Curl.md\",\n{\n 'v': 1247,\n 'f': \"1247\",\n }],\n [\"04_5_Sending_Coins_with_Automated_Raw_Transactions.md\",\n{\n 'v': 608,\n 'f': \"608\",\n }],\n [\"04_6_Creating_a_Segwit_Transaction.md\",\n{\n 'v': 1203,\n 'f': \"1203\",\n }],\n [\"05_0_Controlling_Bitcoin_Transactions.md\",\n{\n 'v': 144,\n 'f': \"144\",\n }],\n [\"05_1_Watching_for_Stuck_Transactions.md\",\n{\n 'v': 588,\n 'f': \"588\",\n }],\n [\"05_2_Resending_a_Transaction_with_RBF.md\",\n{\n 'v': 1412,\n 'f': \"1412\",\n }],\n [\"05_3_Funding_a_Transaction_with_CPFP.md\",\n{\n 'v': 846,\n 'f': \"846\",\n }],\n [\"06_0_Expanding_Bitcoin_Transactions_Multisigs.md\",\n{\n 'v': 148,\n 'f': \"148\",\n }],\n [\"06_1_Sending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1810,\n 'f': \"1810\",\n }],\n [\"06_2_Spending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1131,\n 'f': \"1131\",\n }],\n [\"06_3_Sending_an_Automated_Multisig.md\",\n{\n 'v': 625,\n 'f': \"625\",\n }],\n [\"07_0_Expanding_Bitcoin_Transactions_PSBTs.md\",\n{\n 'v': 163,\n 'f': \"163\",\n }],\n [\"07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1512,\n 'f': \"1512\",\n }],\n [\"07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1383,\n 'f': \"1383\",\n }],\n [\"07_3_Integrating_with_Hardware_Wallets.md\",\n{\n 'v': 2183,\n 'f': \"2183\",\n }],\n [\"08_0_Expanding_Bitcoin_Transactions_Other.md\",\n{\n 'v': 131,\n 'f': \"131\",\n }],\n [\"08_1_Sending_a_Transaction_with_a_Locktime.md\",\n{\n 'v': 1508,\n 'f': \"1508\",\n }],\n [\"08_2_Sending_a_Transaction_with_Data.md\",\n{\n 'v': 596,\n 'f': \"596\",\n }],\n [\"09_0_Introducing_Bitcoin_Scripts.md\",\n{\n 'v': 187,\n 'f': \"187\",\n }],\n [\"09_1_Understanding_the_Foundation_of_Transactions.md\",\n{\n 'v': 993,\n 'f': \"993\",\n }],\n [\"09_2_Running_a_Bitcoin_Script.md\",\n{\n 'v': 887,\n 'f': \"887\",\n }],\n [\"09_3_Testing_a_Bitcoin_Script.md\",\n{\n 'v': 1023,\n 'f': \"1023\",\n }],\n [\"09_4_Scripting_a_P2PKH.md\",\n{\n 'v': 889,\n 'f': \"889\",\n }],\n [\"09_5_Scripting_a_P2WPKH.md\",\n{\n 'v': 881,\n 'f': \"881\",\n }],\n [\"10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md\",\n{\n 'v': 152,\n 'f': \"152\",\n }],\n [\"10_1_Understanding_the_Foundation_of_P2SH.md\",\n{\n 'v': 1179,\n 'f': \"1179\",\n }],\n [\"10_2_Building_the_Structure_of_P2SH.md\",\n{\n 'v': 1318,\n 'f': \"1318\",\n }],\n [\"10_3_Running_a_Bitcoin_Script_with_P2SH.md\",\n{\n 'v': 340,\n 'f': \"340\",\n }],\n [\"10_4_Scripting_a_Multisig.md\",\n{\n 'v': 1043,\n 'f': \"1043\",\n }],\n [\"10_5_Scripting_a_Segwit_Script.md\",\n{\n 'v': 751,\n 'f': \"751\",\n }],\n [\"10_6_Spending_a_P2SH_Transaction.md\",\n{\n 'v': 393,\n 'f': \"393\",\n }],\n [\"11_0_Empowering_Timelock_with_Bitcoin_Scripts.md\",\n{\n 'v': 99,\n 'f': \"99\",\n }],\n [\"11_1_Understanding_Timelock_Options.md\",\n{\n 'v': 571,\n 'f': \"571\",\n }],\n [\"11_2_Using_CLTV_in_Scripts.md\",\n{\n 'v': 1241,\n 'f': \"1241\",\n }],\n [\"11_3_Using_CSV_in_Scripts.md\",\n{\n 'v': 1544,\n 'f': \"1544\",\n }],\n [\"12_0_Expanding_Bitcoin_Scripts.md\",\n{\n 'v': 99,\n 'f': \"99\",\n }],\n [\"12_1_Using_Script_Conditionals.md\",\n{\n 'v': 1216,\n 'f': \"1216\",\n }],\n [\"12_2_Using_Other_Script_Commands.md\",\n{\n 'v': 483,\n 'f': \"483\",\n }],\n [\"13_0_Designing_Real_Bitcoin_Scripts.md\",\n{\n 'v': 112,\n 'f': \"112\",\n }],\n [\"13_1_Writing_Puzzle_Scripts.md\",\n{\n 'v': 1032,\n 'f': \"1032\",\n }],\n [\"13_2_Writing_Complex_Multisig_Scripts.md\",\n{\n 'v': 1031,\n 'f': \"1031\",\n }],\n [\"13_3_Empowering_Bitcoin_with_Scripts.md\",\n{\n 'v': 1493,\n 'f': \"1493\",\n }],\n [\"14_0_Using_Tor.md\",\n{\n 'v': 110,\n 'f': \"110\",\n }],\n [\"14_1_Verifying_Your_Tor_Setup.md\",\n{\n 'v': 1632,\n 'f': \"1632\",\n }],\n [\"14_2_Changing_Your_Bitcoin_Hidden_Services.md\",\n{\n 'v': 460,\n 'f': \"460\",\n }],\n [\"14_3_Adding_SSH_Hidden_Services.md\",\n{\n 'v': 339,\n 'f': \"339\",\n }],\n [\"15_0_Talking_to_Bitcoind.md\",\n{\n 'v': 251,\n 'f': \"251\",\n }],\n [\"15_1_Accessing_Bitcoind_with_C.md\",\n{\n 'v': 1315,\n 'f': \"1315\",\n }],\n [\"15_2_Programming_Bitcoind_with_C.md\",\n{\n 'v': 1484,\n 'f': \"1484\",\n }],\n [\"15_3_Receiving_Bitcoind_Notifications_with_C.md\",\n{\n 'v': 669,\n 'f': \"669\",\n }],\n [\"16_0_Programming_with_Libwally.md\",\n{\n 'v': 317,\n 'f': \"317\",\n }],\n [\"16_1_Setting_Up_Libwally.md\",\n{\n 'v': 583,\n 'f': \"583\",\n }],\n [\"16_2_Using_BIP39_in_Libwally.md\",\n{\n 'v': 958,\n 'f': \"958\",\n }],\n [\"16_3_Using_BIP32_in_Libwally.md\",\n{\n 'v': 978,\n 'f': \"978\",\n }],\n [\"16_4_Using_PSBTs_in_Libwally.md\",\n{\n 'v': 1005,\n 'f': \"1005\",\n }],\n [\"16_5_Using_Scripts_in_Libwally.md\",\n{\n 'v': 789,\n 'f': \"789\",\n }],\n [\"16_6_Using_Other_Functions_in_Libwally.md\",\n{\n 'v': 746,\n 'f': \"746\",\n }],\n [\"16_7_Integrating_Libwally_and_Bitcoin-CLI.md\",\n{\n 'v': 1401,\n 'f': \"1401\",\n }],\n [\"17_0_Talking_to_Bitcoind_Other.md\",\n{\n 'v': 272,\n 'f': \"272\",\n }],\n [\"17_1_Accessing_Bitcoind_with_Go.md\",\n{\n 'v': 697,\n 'f': \"697\",\n }],\n [\"17_2_Accessing_Bitcoind_with_Java.md\",\n{\n 'v': 782,\n 'f': \"782\",\n }],\n [\"17_3_Accessing_Bitcoind_with_NodeJS.md\",\n{\n 'v': 476,\n 'f': \"476\",\n }],\n [\"17_4_Accessing_Bitcoind_with_Python.md\",\n{\n 'v': 1246,\n 'f': \"1246\",\n }],\n [\"17_5_Accessing_Bitcoind_with_Rust.md\",\n{\n 'v': 905,\n 'f': \"905\",\n }],\n [\"17_6_Accessing_Bitcoind_with_Swift.md\",\n{\n 'v': 1588,\n 'f': \"1588\",\n }],\n [\"18_0_Understanding_Your_Lightning_Setup.md\",\n{\n 'v': 185,\n 'f': \"185\",\n }],\n [\"18_1_Verifying_Your_Lightning_Setup.md\",\n{\n 'v': 1347,\n 'f': \"1347\",\n }],\n [\"18_2_Knowing_Your_lightning_Setup.md\",\n{\n 'v': 421,\n 'f': \"421\",\n }],\n [\"18_2__Interlude_Accessing_a_Second_Lightning_Node.md\",\n{\n 'v': 882,\n 'f': \"882\",\n }],\n [\"18_3_Setting_Up_a_Channel.md\",\n{\n 'v': 1219,\n 'f': \"1219\",\n }],\n [\"19_0_Using_Lightning.md\",\n{\n 'v': 145,\n 'f': \"145\",\n }],\n [\"19_1_Generate_a_Payment_Request.md\",\n{\n 'v': 995,\n 'f': \"995\",\n }],\n [\"19_2_Paying_a_Invoice.md\",\n{\n 'v': 614,\n 'f': \"614\",\n }],\n [\"19_3_Closing_a_Channel.md\",\n{\n 'v': 866,\n 'f': \"866\",\n }],\n [\"19_4_Lightning_Network_Review.md\",\n{\n 'v': 677,\n 'f': \"677\",\n }],\n [\"A0_Appendices.md\",\n{\n 'v': 110,\n 'f': \"110\",\n }],\n [\"A1_0_Understanding_Bitcoin_Standup.md\",\n{\n 'v': 412,\n 'f': \"412\",\n }],\n [\"A2_0_Compiling_Bitcoin_from_Source.md\",\n{\n 'v': 414,\n 'f': \"414\",\n }],\n [\"A3_0_Using_Bitcoin_Regtest.md\",\n{\n 'v': 995,\n 'f': \"995\",\n }],\n [\"CLA.md\",\n{\n 'v': 512,\n 'f': \"512\",\n }],\n [\"CONTRIBUTING.md\",\n{\n 'v': 555,\n 'f': \"555\",\n }],\n [\"LICENSE-CC-BY-4.0.md\",\n{\n 'v': 2734,\n 'f': \"2734\",\n }],\n [\"README.md\",\n{\n 'v': 1366,\n 'f': \"1366\",\n }],\n [\"TODO-30.md\",\n{\n 'v': 122,\n 'f': \"122\",\n }],\n [\"TODO.md\",\n{\n 'v': 734,\n 'f': \"734\",\n }]],\n columns: [[\"string\", \"Chapter\"], [\"number\", \"Word Count\"]],\n columnOptions: [],\n rowsPerPage: 25,\n helpUrl: \"https://colab.research.google.com/notebooks/data_table.ipynb\",\n suppressOutputScrolling: true,\n minimumWidth: undefined,\n });\n ", + "text/plain": [ + "" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ChapterWord Count
4401_0_Introduction.md1128
6901_1_Introducing_Bitcoin.md2784
9202_0_Setting_Up_a_Bitcoin-Core_VPS.md221
3302_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackS...1937
6602_2_Setting_Up_Bitcoin_Core_Other.md245
.........
45CONTRIBUTING.md555
34LICENSE-CC-BY-4.0.md2734
0README.md1366
52TODO-30.md122
29TODO.md734
\n", + "

103 rows × 2 columns

\n", + "
" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 39 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "4dFD792BBy0S", + "outputId": "945da188-2d3b-4061-8f23-08e39e6f97f4" + }, + "source": [ + "total_count = chapter_word_counts['Word Count'].sum()\n", + "total_count" + ], + "execution_count": 44, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "89946" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 44 + } + ] + } + ] +} \ No newline at end of file From 85df221a795b02bdd985f3f3a3491b5bda0beb83 Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Fri, 11 Jun 2021 21:27:53 -0500 Subject: [PATCH 02/50] removing np import, re-running output --- word_count.ipynb | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/word_count.ipynb b/word_count.ipynb index 7a19a21..7722901 100644 --- a/word_count.ipynb +++ b/word_count.ipynb @@ -5,7 +5,7 @@ "colab": { "name": "Untitled25.ipynb", "provenance": [], - "authorship_tag": "ABX9TyOJqhnf6/YgfQMx6pfh6Fth", + "authorship_tag": "ABX9TyMioTaWOtZ3dcIebltCT4IN", "include_colab_link": true }, "kernelspec": { @@ -33,11 +33,10 @@ "id": "kT4wyWuy2szs" }, "source": [ - "import numpy as np\n", "import os\n", "import pandas as pd" ], - "execution_count": 7, + "execution_count": 1, "outputs": [] }, { @@ -47,7 +46,7 @@ "base_uri": "https://localhost:8080/" }, "id": "9J62Uh4H2Y9g", - "outputId": "f4147b98-f72a-4ad2-8b5b-c3bb9f0c86db" + "outputId": "0ac3147d-fdb4-4b9c-d96b-4da334730a93" }, "source": [ "!git clone https://github.com/icculp/Learning-Bitcoin-from-the-Command-Line.git" @@ -58,12 +57,12 @@ "output_type": "stream", "text": [ "Cloning into 'Learning-Bitcoin-from-the-Command-Line'...\n", - "remote: Enumerating objects: 6634, done.\u001b[K\n", - "remote: Counting objects: 100% (238/238), done.\u001b[K\n", - "remote: Compressing objects: 100% (196/196), done.\u001b[K\n", - "remote: Total 6634 (delta 109), reused 82 (delta 42), pack-reused 6396\u001b[K\n", - "Receiving objects: 100% (6634/6634), 7.53 MiB | 13.87 MiB/s, done.\n", - "Resolving deltas: 100% (4068/4068), done.\n" + "remote: Enumerating objects: 6637, done.\u001b[K\n", + "remote: Counting objects: 100% (241/241), done.\u001b[K\n", + "remote: Compressing objects: 100% (199/199), done.\u001b[K\n", + "remote: Total 6637 (delta 110), reused 82 (delta 42), pack-reused 6396\u001b[K\n", + "Receiving objects: 100% (6637/6637), 7.53 MiB | 18.46 MiB/s, done.\n", + "Resolving deltas: 100% (4069/4069), done.\n" ], "name": "stdout" } @@ -103,7 +102,7 @@ " # print(chapter, count)\n", " return pd.DataFrame(counts, columns=columns)" ], - "execution_count": 35, + "execution_count": 3, "outputs": [] }, { @@ -115,7 +114,7 @@ "chapter_word_counts = count_words()\n", "chapter_word_counts.sort_values(by=['Chapter'], inplace=True)" ], - "execution_count": 38, + "execution_count": 4, "outputs": [] }, { @@ -126,13 +125,13 @@ "height": 631 }, "id": "IPkG4oQJ6f1e", - "outputId": "d057cf19-4d40-477a-964c-d2b6154e1e73" + "outputId": "eea2f4b6-c3d3-48b5-dc62-97885c18d48d" }, "source": [ "from google.colab import data_table\n", "data_table.DataTable(chapter_word_counts, include_index=False)" ], - "execution_count": 39, + "execution_count": 5, "outputs": [ { "output_type": "execute_result", @@ -229,7 +228,7 @@ "metadata": { "tags": [] }, - "execution_count": 39 + "execution_count": 5 } ] }, @@ -240,13 +239,13 @@ "base_uri": "https://localhost:8080/" }, "id": "4dFD792BBy0S", - "outputId": "945da188-2d3b-4061-8f23-08e39e6f97f4" + "outputId": "3c4dc4ff-ceb3-4ff5-d40d-c606eec83a8c" }, "source": [ "total_count = chapter_word_counts['Word Count'].sum()\n", "total_count" ], - "execution_count": 44, + "execution_count": 6, "outputs": [ { "output_type": "execute_result", @@ -258,7 +257,7 @@ "metadata": { "tags": [] }, - "execution_count": 44 + "execution_count": 6 } ] } From 4fdae44c5c780cc767edd306ddd8cabc71325586 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 15 Jun 2021 10:43:08 -1000 Subject: [PATCH 03/50] updated to explain translation branch --- TRANSLATING.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/TRANSLATING.md b/TRANSLATING.md index 0b786a9..cb68af5 100644 --- a/TRANSLATING.md +++ b/TRANSLATING.md @@ -9,12 +9,14 @@ Thank you for your interest in translating Learning Bitcoin from the Command Lin * Choose a [Release](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/releases) as the basis of your translation. We generally suggest the latest release. This will ensure the consistency of all the files in your translation, will insulate you from any changes we make, and will make it easy to see what has changed when we create a new release. * If it looks like there hasn't been a new Release in a while, file an Issue saying you're interested in starting a new translation, and asking if it would make sense for there to be a new Release milestone before you do so. If there's been anything notable, and we're not in the middle of things, we'll likely create a new patch or minor version. If we're in the middle of things, we'll just suggest you use the previous Release. * Label your table of contents and each chapter or section with the release used. -1. **Create a Branch.** - * All work should be done in a branch, with work being submitted to the `master` branch as PRs. -1. **Create a Directory.** - * Create a top-level directory for your complete translation using the [ISO 639-1 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), for example `es` (Spanish), `fr` (French), or `pt` (Portuguese). +1. **Request a Branch.** + * File an [Issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) requesting a new branch for your translation + * This will be the master place for us to collect work on the translation over time. + * We will create a top-level directory for your complete translation using the [ISO 639-1 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), for example `es` (Spanish), `fr` (French), or `pt` (Portuguese). Work should be done in that directory. +1. **Branch the Branch.** + * Once we've created a translation branch, you'll then want to branch that into your own GitHub account. 1. **Submit PRs a Chapter at a Time.** - * Submit your PRs for the translation in batches of no more than a single chapter at a time. + * Submit your PRs for the translation from your working branch to our translation branch in batches of no more than a single chapter at a time. * Submit in smaller batches if it makes sense, for example because different people are writing different sections. 1. **Request Approval from a Native Speaker.** * No one can ever do a great edit of their own work, so we require each section to be approved by someone other than the original translator. @@ -24,6 +26,9 @@ Thank you for your interest in translating Learning Bitcoin from the Command Lin 1. **Continue!** * Continue through the process, no more than one chapter at a time, until you have a full book. * Be aware of the scope of the overall project. As of v2.01, Learning Bitcoin from the Command Line is 120,000 words in length. As a book, that'd be 250-400 pages, depending on the format and layout. (About 80,000 words of that is text to translate, with the remainder being code.) You want to make sure you have the time for that level of commitment before getting started. +1. **Let Us Know When You're Done.** + * When you've completed your translation, file an issue to let us know that the translation branch is ready to be merged into the master. + * This will also let us know to announce the completed translation and link it into the master README 1. **Update Your Translation with New Releases** * It is our hope that translations will stay up to day with new releases, particularly major and minor releases, which are likely to include new content and updates. Currently, these only occur ever few years * If you have decided to stop updating a translation, please let us know in an Issue, so that we can let the community know that we are looking for a new translator to continue updating a translation. From a47fd6ef3938db63149a227efd35125e8d28a7c8 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Wed, 16 Jun 2021 15:21:29 -1000 Subject: [PATCH 04/50] Update TRANSLATING.md --- TRANSLATING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TRANSLATING.md b/TRANSLATING.md index cb68af5..2d3c16b 100644 --- a/TRANSLATING.md +++ b/TRANSLATING.md @@ -13,10 +13,10 @@ Thank you for your interest in translating Learning Bitcoin from the Command Lin * File an [Issue](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) requesting a new branch for your translation * This will be the master place for us to collect work on the translation over time. * We will create a top-level directory for your complete translation using the [ISO 639-1 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), for example `es` (Spanish), `fr` (French), or `pt` (Portuguese). Work should be done in that directory. -1. **Branch the Branch.** - * Once we've created a translation branch, you'll then want to branch that into your own GitHub account. +1. **Fork the Branch.** + * Once we've created a translation branch, you'll then want to fork that into your own GitHub account. 1. **Submit PRs a Chapter at a Time.** - * Submit your PRs for the translation from your working branch to our translation branch in batches of no more than a single chapter at a time. + * Submit your PRs for the translation from your working fork to our translation branch in batches of no more than a single chapter at a time. * Submit in smaller batches if it makes sense, for example because different people are writing different sections. 1. **Request Approval from a Native Speaker.** * No one can ever do a great edit of their own work, so we require each section to be approved by someone other than the original translator. From ae7c0f6c21a12c7677550ef6aa35eec57097914e Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 21:33:52 -0500 Subject: [PATCH 05/50] Rename word_count.ipynb to word_count_old.ipynb --- word_count.ipynb => word_count_old.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename word_count.ipynb => word_count_old.ipynb (99%) diff --git a/word_count.ipynb b/word_count_old.ipynb similarity index 99% rename from word_count.ipynb rename to word_count_old.ipynb index 7722901..62bd3e6 100644 --- a/word_count.ipynb +++ b/word_count_old.ipynb @@ -262,4 +262,4 @@ ] } ] -} \ No newline at end of file +} From db2d05f8705e1b291a71246720110ce22a839035 Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 21:34:56 -0500 Subject: [PATCH 06/50] Updated for markdown + edge cases --- Chapter_word_count.ipynb | 362 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 Chapter_word_count.ipynb diff --git a/Chapter_word_count.ipynb b/Chapter_word_count.ipynb new file mode 100644 index 0000000..8ce5aff --- /dev/null +++ b/Chapter_word_count.ipynb @@ -0,0 +1,362 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Untitled25.ipynb", + "provenance": [], + "authorship_tag": "ABX9TyNJdlLdL56gLSWYqG177B0A", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TQUe8ZZed-Bp" + }, + "source": [ + "Run in colab by clicking the link above to view the results as a paginated table with word counts for each chapter near the bottom of the notebook. Total word count at the very bottom." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X7D8JEIgy9fV" + }, + "source": [ + "This notebook counts through the translatable words of each chapter, including chapter links; ignores code blocks, markdown characters, and tokens containing digits." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kT4wyWuy2szs" + }, + "source": [ + "import os\n", + "import pandas as pd\n", + "import re" + ], + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "9J62Uh4H2Y9g", + "outputId": "8d2c4675-ddf9-4cd5-8fb2-ee4cae9b034d" + }, + "source": [ + "!git clone https://github.com/icculp/Learning-Bitcoin-from-the-Command-Line.git" + ], + "execution_count": 2, + "outputs": [ + { + "output_type": "stream", + "text": [ + "fatal: destination path 'Learning-Bitcoin-from-the-Command-Line' already exists and is not an empty directory.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k_g4-Fvn2yPy" + }, + "source": [ + "def count_words():\n", + " \"\"\" Counts words ignoring code blocks and digits\n", + "\n", + " To test for quality:\n", + " lines 14-16 to test a single chapter\n", + " uncomment line 45 to view accepted word tokens\n", + " uncomment line \n", + " \"\"\"\n", + " columns=['Chapter', 'Word Count']\n", + " counts = []\n", + " repo_path = '/content/Learning-Bitcoin-from-the-Command-Line/'\n", + " for chapter in os.listdir(repo_path):\n", + " ''' uncomment lines 8-10 to test a single chapter, replacing ch_name\n", + " with the name you want to test\n", + " '''\n", + " #ch_name = '03_2_Knowing_Your_Bitcoin_Setup.md'\n", + " #if chapter != ch_name:\n", + " # continue\n", + " ignore_list = ['bitcoin.conf-annotated.txt', 'TODO.md', 'TODO-30.md']\n", + " if chapter in ignore_list or\\\n", + " not chapter.endswith('md'): # g\n", + " continue\n", + " count = 0\n", + " flag = 0 # ignores words between code markdown ```\n", + " with open(repo_path + chapter) as ch:\n", + " for line in ch.readlines():\n", + " if flag:\n", + " if '```' in line[:3].replace(' ', ''):\n", + " flag = 0\n", + " continue\n", + " continue\n", + " if '```' in line:\n", + " flag = 1\n", + " continue\n", + " for word in line.split():\n", + " if '.md' in word:\n", + " ch_link_tokens = word.split('_')\n", + " if ']' in word: # indicates trailing link with chapter name; counts last word of trailing link before chapter name\n", + " count += 1\n", + " link_tokens_count = len(ch_link_tokens[2:]) # ignoring chapter numbers in chapter link tokens\n", + " count += link_tokens_count\n", + " # print(word, '[TOK]', link_tokens_count, end='[SEPTOK]')\n", + " continue\n", + " ignore = ['*', '**', '#', '##', '###', '####',\n", + " '-', '—', '>', '`', '/', '&', '|', '~']\n", + " if any(ch.isdigit() for ch in word) or\\\n", + " word in ignore or\\\n", + " '`' in word or\\\n", + " '~/' in word or\\\n", + " '/.' in word or\\\n", + " '|-' in word or\\\n", + " (word[0] == ':' and word[-1] == ':') or\\\n", + " (word[0] == '\"' and word[-1] == '\"'):\n", + " # print(word) # , end='[SEP]') # view rejected tokens\n", + " continue\n", + " # print(word, count) # , end='[SEP]') # view accepted tokens\n", + " count += 1\n", + " counts.append((chapter, count))\n", + " # print(chapter, count)\n", + " return pd.DataFrame(counts, columns=columns)" + ], + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2-pkEaYF3Uxm" + }, + "source": [ + "chapter_word_counts = count_words()\n", + "chapter_word_counts.sort_values(by=['Chapter'], inplace=True)\n", + "# view accepted or rejected tokens below if line 53 or 51 uncommented in count_words(), respectively" + ], + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 631 + }, + "id": "K73GH7UFmwI5", + "outputId": "d1430339-8b1b-43f3-cdcf-1019948c7b9c" + }, + "source": [ + "from google.colab import data_table\n", + "data_table.DataTable(chapter_word_counts, include_index=False)" + ], + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.module+javascript": "\n import \"https://ssl.gstatic.com/colaboratory/data_table/a6224c040fa35dcf/data_table.js\";\n\n window.createDataTable({\n data: [[\"01_0_Introduction.md\",\n{\n 'v': 1144,\n 'f': \"1144\",\n }],\n [\"01_1_Introducing_Bitcoin.md\",\n{\n 'v': 2735,\n 'f': \"2735\",\n }],\n [\"02_0_Setting_Up_a_Bitcoin-Core_VPS.md\",\n{\n 'v': 226,\n 'f': \"226\",\n }],\n [\"02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md\",\n{\n 'v': 2723,\n 'f': \"2723\",\n }],\n [\"02_2_Setting_Up_Bitcoin_Core_Other.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"03_0_Understanding_Your_Bitcoin_Setup.md\",\n{\n 'v': 248,\n 'f': \"248\",\n }],\n [\"03_1_Verifying_Your_Bitcoin_Setup.md\",\n{\n 'v': 773,\n 'f': \"773\",\n }],\n [\"03_2_Knowing_Your_Bitcoin_Setup.md\",\n{\n 'v': 517,\n 'f': \"517\",\n }],\n [\"03_3_Setting_Up_Your_Wallet.md\",\n{\n 'v': 1699,\n 'f': \"1699\",\n }],\n [\"03_3__Interlude_Using_Command-Line_Variables.md\",\n{\n 'v': 347,\n 'f': \"347\",\n }],\n [\"03_4_Receiving_a_Transaction.md\",\n{\n 'v': 1479,\n 'f': \"1479\",\n }],\n [\"03_5_Understanding_the_Descriptor.md\",\n{\n 'v': 1349,\n 'f': \"1349\",\n }],\n [\"04_0_Sending_Bitcoin_Transactions.md\",\n{\n 'v': 176,\n 'f': \"176\",\n }],\n [\"04_1_Sending_Coins_The_Easy_Way.md\",\n{\n 'v': 1068,\n 'f': \"1068\",\n }],\n [\"04_2_Creating_a_Raw_Transaction.md\",\n{\n 'v': 1720,\n 'f': \"1720\",\n }],\n [\"04_2__Interlude_Using_JQ.md\",\n{\n 'v': 1956,\n 'f': \"1956\",\n }],\n [\"04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md\",\n{\n 'v': 413,\n 'f': \"413\",\n }],\n [\"04_4_Sending_Coins_with_a_Raw_Transaction.md\",\n{\n 'v': 1024,\n 'f': \"1024\",\n }],\n [\"04_4__Interlude_Using_Curl.md\",\n{\n 'v': 1643,\n 'f': \"1643\",\n }],\n [\"04_5_Sending_Coins_with_Automated_Raw_Transactions.md\",\n{\n 'v': 614,\n 'f': \"614\",\n }],\n [\"04_6_Creating_a_Segwit_Transaction.md\",\n{\n 'v': 1172,\n 'f': \"1172\",\n }],\n [\"05_0_Controlling_Bitcoin_Transactions.md\",\n{\n 'v': 149,\n 'f': \"149\",\n }],\n [\"05_1_Watching_for_Stuck_Transactions.md\",\n{\n 'v': 595,\n 'f': \"595\",\n }],\n [\"05_2_Resending_a_Transaction_with_RBF.md\",\n{\n 'v': 1372,\n 'f': \"1372\",\n }],\n [\"05_3_Funding_a_Transaction_with_CPFP.md\",\n{\n 'v': 827,\n 'f': \"827\",\n }],\n [\"06_0_Expanding_Bitcoin_Transactions_Multisigs.md\",\n{\n 'v': 155,\n 'f': \"155\",\n }],\n [\"06_1_Sending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1764,\n 'f': \"1764\",\n }],\n [\"06_2_Spending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1079,\n 'f': \"1079\",\n }],\n [\"06_3_Sending_an_Automated_Multisig.md\",\n{\n 'v': 613,\n 'f': \"613\",\n }],\n [\"07_0_Expanding_Bitcoin_Transactions_PSBTs.md\",\n{\n 'v': 169,\n 'f': \"169\",\n }],\n [\"07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1393,\n 'f': \"1393\",\n }],\n [\"07_3_Integrating_with_Hardware_Wallets.md\",\n{\n 'v': 2150,\n 'f': \"2150\",\n }],\n [\"08_0_Expanding_Bitcoin_Transactions_Other.md\",\n{\n 'v': 139,\n 'f': \"139\",\n }],\n [\"08_1_Sending_a_Transaction_with_a_Locktime.md\",\n{\n 'v': 1483,\n 'f': \"1483\",\n }],\n [\"08_2_Sending_a_Transaction_with_Data.md\",\n{\n 'v': 580,\n 'f': \"580\",\n }],\n [\"09_0_Introducing_Bitcoin_Scripts.md\",\n{\n 'v': 196,\n 'f': \"196\",\n }],\n [\"09_1_Understanding_the_Foundation_of_Transactions.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"09_2_Running_a_Bitcoin_Script.md\",\n{\n 'v': 863,\n 'f': \"863\",\n }],\n [\"09_3_Testing_a_Bitcoin_Script.md\",\n{\n 'v': 1000,\n 'f': \"1000\",\n }],\n [\"09_4_Scripting_a_P2PKH.md\",\n{\n 'v': 838,\n 'f': \"838\",\n }],\n [\"09_5_Scripting_a_P2WPKH.md\",\n{\n 'v': 845,\n 'f': \"845\",\n }],\n [\"10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md\",\n{\n 'v': 170,\n 'f': \"170\",\n }],\n [\"10_1_Understanding_the_Foundation_of_P2SH.md\",\n{\n 'v': 1164,\n 'f': \"1164\",\n }],\n [\"10_2_Building_the_Structure_of_P2SH.md\",\n{\n 'v': 1284,\n 'f': \"1284\",\n }],\n [\"10_3_Running_a_Bitcoin_Script_with_P2SH.md\",\n{\n 'v': 323,\n 'f': \"323\",\n }],\n [\"10_4_Scripting_a_Multisig.md\",\n{\n 'v': 1016,\n 'f': \"1016\",\n }],\n [\"10_5_Scripting_a_Segwit_Script.md\",\n{\n 'v': 750,\n 'f': \"750\",\n }],\n [\"10_6_Spending_a_P2SH_Transaction.md\",\n{\n 'v': 384,\n 'f': \"384\",\n }],\n [\"11_0_Empowering_Timelock_with_Bitcoin_Scripts.md\",\n{\n 'v': 108,\n 'f': \"108\",\n }],\n [\"11_1_Understanding_Timelock_Options.md\",\n{\n 'v': 557,\n 'f': \"557\",\n }],\n [\"11_2_Using_CLTV_in_Scripts.md\",\n{\n 'v': 1197,\n 'f': \"1197\",\n }],\n [\"11_3_Using_CSV_in_Scripts.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"12_0_Expanding_Bitcoin_Scripts.md\",\n{\n 'v': 99,\n 'f': \"99\",\n }],\n [\"12_1_Using_Script_Conditionals.md\",\n{\n 'v': 1120,\n 'f': \"1120\",\n }],\n [\"12_2_Using_Other_Script_Commands.md\",\n{\n 'v': 407,\n 'f': \"407\",\n }],\n [\"13_0_Designing_Real_Bitcoin_Scripts.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"13_1_Writing_Puzzle_Scripts.md\",\n{\n 'v': 998,\n 'f': \"998\",\n }],\n [\"13_2_Writing_Complex_Multisig_Scripts.md\",\n{\n 'v': 996,\n 'f': \"996\",\n }],\n [\"13_3_Empowering_Bitcoin_with_Scripts.md\",\n{\n 'v': 1467,\n 'f': \"1467\",\n }],\n [\"14_0_Using_Tor.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"14_1_Verifying_Your_Tor_Setup.md\",\n{\n 'v': 1568,\n 'f': \"1568\",\n }],\n [\"14_2_Changing_Your_Bitcoin_Hidden_Services.md\",\n{\n 'v': 434,\n 'f': \"434\",\n }],\n [\"14_3_Adding_SSH_Hidden_Services.md\",\n{\n 'v': 330,\n 'f': \"330\",\n }],\n [\"15_0_Talking_to_Bitcoind.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"15_1_Accessing_Bitcoind_with_C.md\",\n{\n 'v': 1238,\n 'f': \"1238\",\n }],\n [\"15_2_Programming_Bitcoind_with_C.md\",\n{\n 'v': 1427,\n 'f': \"1427\",\n }],\n [\"15_3_Receiving_Bitcoind_Notifications_with_C.md\",\n{\n 'v': 650,\n 'f': \"650\",\n }],\n [\"16_0_Programming_with_Libwally.md\",\n{\n 'v': 333,\n 'f': \"333\",\n }],\n [\"16_1_Setting_Up_Libwally.md\",\n{\n 'v': 559,\n 'f': \"559\",\n }],\n [\"16_2_Using_BIP39_in_Libwally.md\",\n{\n 'v': 939,\n 'f': \"939\",\n }],\n [\"16_3_Using_BIP32_in_Libwally.md\",\n{\n 'v': 959,\n 'f': \"959\",\n }],\n [\"16_4_Using_PSBTs_in_Libwally.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"16_5_Using_Scripts_in_Libwally.md\",\n{\n 'v': 785,\n 'f': \"785\",\n }],\n [\"16_6_Using_Other_Functions_in_Libwally.md\",\n{\n 'v': 655,\n 'f': \"655\",\n }],\n [\"16_7_Integrating_Libwally_and_Bitcoin-CLI.md\",\n{\n 'v': 1380,\n 'f': \"1380\",\n }],\n [\"17_0_Talking_to_Bitcoind_Other.md\",\n{\n 'v': 286,\n 'f': \"286\",\n }],\n [\"17_1_Accessing_Bitcoind_with_Go.md\",\n{\n 'v': 547,\n 'f': \"547\",\n }],\n [\"17_2_Accessing_Bitcoind_with_Java.md\",\n{\n 'v': 821,\n 'f': \"821\",\n }],\n [\"17_3_Accessing_Bitcoind_with_NodeJS.md\",\n{\n 'v': 393,\n 'f': \"393\",\n }],\n [\"17_4_Accessing_Bitcoind_with_Python.md\",\n{\n 'v': 1158,\n 'f': \"1158\",\n }],\n [\"17_5_Accessing_Bitcoind_with_Rust.md\",\n{\n 'v': 829,\n 'f': \"829\",\n }],\n [\"17_6_Accessing_Bitcoind_with_Swift.md\",\n{\n 'v': 1503,\n 'f': \"1503\",\n }],\n [\"18_0_Understanding_Your_Lightning_Setup.md\",\n{\n 'v': 192,\n 'f': \"192\",\n }],\n [\"18_1_Verifying_Your_Lightning_Setup.md\",\n{\n 'v': 1294,\n 'f': \"1294\",\n }],\n [\"18_2_Knowing_Your_lightning_Setup.md\",\n{\n 'v': 399,\n 'f': \"399\",\n }],\n [\"18_2__Interlude_Accessing_a_Second_Lightning_Node.md\",\n{\n 'v': 886,\n 'f': \"886\",\n }],\n [\"18_3_Setting_Up_a_Channel.md\",\n{\n 'v': 1173,\n 'f': \"1173\",\n }],\n [\"19_0_Using_Lightning.md\",\n{\n 'v': 146,\n 'f': \"146\",\n }],\n [\"19_1_Generate_a_Payment_Request.md\",\n{\n 'v': 968,\n 'f': \"968\",\n }],\n [\"19_2_Paying_a_Invoice.md\",\n{\n 'v': 604,\n 'f': \"604\",\n }],\n [\"19_3_Closing_a_Channel.md\",\n{\n 'v': 848,\n 'f': \"848\",\n }],\n [\"19_4_Lightning_Network_Review.md\",\n{\n 'v': 626,\n 'f': \"626\",\n }],\n [\"A0_Appendices.md\",\n{\n 'v': 112,\n 'f': \"112\",\n }],\n [\"A1_0_Understanding_Bitcoin_Standup.md\",\n{\n 'v': 420,\n 'f': \"420\",\n }],\n [\"A2_0_Compiling_Bitcoin_from_Source.md\",\n{\n 'v': 412,\n 'f': \"412\",\n }],\n [\"A3_0_Using_Bitcoin_Regtest.md\",\n{\n 'v': 980,\n 'f': \"980\",\n }],\n [\"CLA.md\",\n{\n 'v': 495,\n 'f': \"495\",\n }],\n [\"CONTRIBUTING.md\",\n{\n 'v': 529,\n 'f': \"529\",\n }],\n [\"LICENSE-CC-BY-4.0.md\",\n{\n 'v': 2716,\n 'f': \"2716\",\n }],\n [\"README.md\",\n{\n 'v': 1687,\n 'f': \"1687\",\n }]],\n columns: [[\"string\", \"Chapter\"], [\"number\", \"Word Count\"]],\n columnOptions: [],\n rowsPerPage: 25,\n helpUrl: \"https://colab.research.google.com/notebooks/data_table.ipynb\",\n suppressOutputScrolling: true,\n minimumWidth: undefined,\n });\n ", + "text/plain": [ + "" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ChapterWord Count
7201_0_Introduction.md1144
2101_1_Introducing_Bitcoin.md2735
2002_0_Setting_Up_a_Bitcoin-Core_VPS.md226
9702_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackS...2723
9402_2_Setting_Up_Bitcoin_Core_Other.md254
.........
45A3_0_Using_Bitcoin_Regtest.md980
38CLA.md495
74CONTRIBUTING.md529
53LICENSE-CC-BY-4.0.md2716
2README.md1687
\n", + "

101 rows × 2 columns

\n", + "
" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "_gGsbGDckIrC", + "outputId": "a9811107-2a07-464a-d96a-c6767e5ea7d4" + }, + "source": [ + "total_count = chapter_word_counts['Word Count'].sum()\n", + "total_count" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "88215" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 6 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "14kdusmNzcfz" + }, + "source": [ + "To convert the table to a markdown format and save as 'Chapter_word_counts.md', run the cells below" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uc7eKo9TkidD" + }, + "source": [ + "from IPython.display import Markdown, display\n", + "from tabulate import tabulate\n", + "\n", + "\n", + "# borrowed from https://stackoverflow.com/questions/33181846/programmatically-convert-pandas-dataframe-to-markdown-table\n", + "\n", + "def pandas_df_to_markdown_table(df):\n", + " fmt = ['---' for i in range(len(df.columns))]\n", + " df_fmt = pd.DataFrame([fmt], columns=df.columns)\n", + " df_formatted = pd.concat([df_fmt, df])\n", + " return Markdown(df_formatted.to_csv(sep=\"|\", index=False))\n", + "\n", + "def df_to_markdown(df, y_index=False):\n", + " blob = tabulate(df, headers='keys', tablefmt='pipe')\n", + " if not y_index:\n", + " return '\\n'.join(['| {}'.format(row.split('|', 2)[-1]) for row in blob.split('\\n')])\n", + " return blob" + ], + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y0QVAGKqzWX6" + }, + "source": [ + "mkt = pandas_df_to_markdown_table(chapter_word_counts)\n", + "\n", + "with open('Chapter_word_counts.md', 'w') as m:\n", + " m.write(str(mkt.data))" + ], + "execution_count": 8, + "outputs": [] + } + ] +} \ No newline at end of file From 0568399ecc153077948193c91e3c7543f37eacb1 Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 22:14:09 -0500 Subject: [PATCH 07/50] Created using Colaboratory --- Chapter_word_counts.ipynb | 377 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 Chapter_word_counts.ipynb diff --git a/Chapter_word_counts.ipynb b/Chapter_word_counts.ipynb new file mode 100644 index 0000000..e404454 --- /dev/null +++ b/Chapter_word_counts.ipynb @@ -0,0 +1,377 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Untitled25.ipynb", + "provenance": [], + "authorship_tag": "ABX9TyNHQ/J52I0G+daf1wNCNdAI", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X7D8JEIgy9fV" + }, + "source": [ + "This notebook counts through the translatable words of each chapter, including chapter links; ignores code blocks, markdown characters, and tokens containing digits." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TQUe8ZZed-Bp" + }, + "source": [ + "Run in colab by clicking the link above to view the results as a paginated table with word counts for each chapter near the bottom of the notebook. Total word count at the very bottom." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kT4wyWuy2szs" + }, + "source": [ + "import os\n", + "import pandas as pd" + ], + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "9J62Uh4H2Y9g", + "outputId": "3295f8b2-5255-4eac-bc78-3da247037c41" + }, + "source": [ + "!git clone https://github.com/icculp/Learning-Bitcoin-from-the-Command-Line.git" + ], + "execution_count": 2, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Cloning into 'Learning-Bitcoin-from-the-Command-Line'...\n", + "remote: Enumerating objects: 6715, done.\u001b[K\n", + "remote: Counting objects: 100% (319/319), done.\u001b[K\n", + "remote: Compressing objects: 100% (193/193), done.\u001b[K\n", + "remote: Total 6715 (delta 157), reused 277 (delta 125), pack-reused 6396\u001b[K\n", + "Receiving objects: 100% (6715/6715), 7.56 MiB | 22.84 MiB/s, done.\n", + "Resolving deltas: 100% (4116/4116), done.\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "k_g4-Fvn2yPy" + }, + "source": [ + "def count_words():\n", + " \"\"\" Counts words ignoring code blocks and digits\n", + " To test for quality:\n", + " lines 16-18 to test a single chapter\n", + " uncomment line 31 to view skipped code block sections\n", + " uncomment line 55 to view rejected word tokens (not including code blocks)\n", + " uncomment line 57 to view accepted word tokens\n", + " but not at the same time, and best one chapter at a time\n", + " \"\"\"\n", + " counts = []\n", + " repo_path = '/content/Learning-Bitcoin-from-the-Command-Line/'\n", + " for chapter in os.listdir(repo_path):\n", + " ''' uncomment lines 16-18 to test a single chapter, replacing\n", + " ch_name with the name you want to test\n", + " '''\n", + " #ch_name = '04_2__Interlude_Using_JQ.md'\n", + " #if chapter != ch_name:\n", + " # continue\n", + " ignore_list = ['bitcoin.conf-annotated.txt', 'TODO.md', 'TODO-30.md']\n", + " if chapter in ignore_list or\\\n", + " not chapter.endswith('md'):\n", + " continue\n", + " count = 0\n", + " flag = 0 # ignores words between code markdown ```\n", + " with open(repo_path + chapter) as ch:\n", + " for line in ch.readlines():\n", + " if flag:\n", + " if '```' in line[:3].replace(' ', ''): # chars can't precede code closing markdown\n", + " flag = 0\n", + " continue\n", + " # print(line) # view uncounted code blocks\n", + " continue\n", + " if '```' in line:\n", + " flag = 1\n", + " continue\n", + " for word in line.split():\n", + " if '.md' in word: # indicates trailing link with chapter name;\n", + " ch_link_tokens = word.split('_')\n", + " if ']' in word: # counts last word of trailing link before chapter name\n", + " count += 1\n", + " link_tokens_count = len(ch_link_tokens[2:]) # ignoring chapter numbers\n", + " count += link_tokens_count\n", + " # print(word, '[TOK]', link_tokens_count, end='[SEPTOK]')\n", + " continue\n", + " ignore = ['*', '**', '#', '##', '###', '####',\n", + " '-', '—', '>', '`', '/', '&', '|', '~']\n", + " if any(ch.isdigit() for ch in word) or\\\n", + " word in ignore or\\\n", + " '`' in word or\\\n", + " '~/' in word or\\\n", + " '/.' in word or\\\n", + " '|-' in word or\\\n", + " (word[0] == ':' and word[-1] == ':') or\\\n", + " (word[0] == '\"' and word[-1] == '\"'):\n", + " # print(word) # , end='[SEP]') # view rejected tokens\n", + " continue\n", + " # print(word, count) # , end='[SEP]') # view accepted tokens\n", + " count += 1\n", + " counts.append((chapter, count))\n", + " # print(chapter, count)\n", + " return pd.DataFrame(counts, columns=['Chapter', 'Word Count'])" + ], + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2-pkEaYF3Uxm" + }, + "source": [ + "chapter_word_counts = count_words()\n", + "chapter_word_counts.sort_values(by=['Chapter'], inplace=True)\n", + "# view accepted or rejected tokens below if line 55 or 53 uncommented in count_words(), respectively" + ], + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZIUumQnh9C_1" + }, + "source": [ + "View in colab for paginated table" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 631 + }, + "id": "K73GH7UFmwI5", + "outputId": "246c0b17-0854-4811-c67f-8081d7950272" + }, + "source": [ + "from google.colab import data_table\n", + "data_table.DataTable(chapter_word_counts, include_index=False)" + ], + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.google.colaboratory.module+javascript": "\n import \"https://ssl.gstatic.com/colaboratory/data_table/a6224c040fa35dcf/data_table.js\";\n\n window.createDataTable({\n data: [[\"01_0_Introduction.md\",\n{\n 'v': 1144,\n 'f': \"1144\",\n }],\n [\"01_1_Introducing_Bitcoin.md\",\n{\n 'v': 2735,\n 'f': \"2735\",\n }],\n [\"02_0_Setting_Up_a_Bitcoin-Core_VPS.md\",\n{\n 'v': 226,\n 'f': \"226\",\n }],\n [\"02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md\",\n{\n 'v': 2746,\n 'f': \"2746\",\n }],\n [\"02_2_Setting_Up_Bitcoin_Core_Other.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"03_0_Understanding_Your_Bitcoin_Setup.md\",\n{\n 'v': 248,\n 'f': \"248\",\n }],\n [\"03_1_Verifying_Your_Bitcoin_Setup.md\",\n{\n 'v': 773,\n 'f': \"773\",\n }],\n [\"03_2_Knowing_Your_Bitcoin_Setup.md\",\n{\n 'v': 517,\n 'f': \"517\",\n }],\n [\"03_3_Setting_Up_Your_Wallet.md\",\n{\n 'v': 1699,\n 'f': \"1699\",\n }],\n [\"03_3__Interlude_Using_Command-Line_Variables.md\",\n{\n 'v': 347,\n 'f': \"347\",\n }],\n [\"03_4_Receiving_a_Transaction.md\",\n{\n 'v': 1479,\n 'f': \"1479\",\n }],\n [\"03_5_Understanding_the_Descriptor.md\",\n{\n 'v': 1349,\n 'f': \"1349\",\n }],\n [\"04_0_Sending_Bitcoin_Transactions.md\",\n{\n 'v': 176,\n 'f': \"176\",\n }],\n [\"04_1_Sending_Coins_The_Easy_Way.md\",\n{\n 'v': 1195,\n 'f': \"1195\",\n }],\n [\"04_2_Creating_a_Raw_Transaction.md\",\n{\n 'v': 1720,\n 'f': \"1720\",\n }],\n [\"04_2__Interlude_Using_JQ.md\",\n{\n 'v': 1956,\n 'f': \"1956\",\n }],\n [\"04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md\",\n{\n 'v': 413,\n 'f': \"413\",\n }],\n [\"04_4_Sending_Coins_with_a_Raw_Transaction.md\",\n{\n 'v': 1024,\n 'f': \"1024\",\n }],\n [\"04_4__Interlude_Using_Curl.md\",\n{\n 'v': 1643,\n 'f': \"1643\",\n }],\n [\"04_5_Sending_Coins_with_Automated_Raw_Transactions.md\",\n{\n 'v': 614,\n 'f': \"614\",\n }],\n [\"04_6_Creating_a_Segwit_Transaction.md\",\n{\n 'v': 1172,\n 'f': \"1172\",\n }],\n [\"05_0_Controlling_Bitcoin_Transactions.md\",\n{\n 'v': 149,\n 'f': \"149\",\n }],\n [\"05_1_Watching_for_Stuck_Transactions.md\",\n{\n 'v': 595,\n 'f': \"595\",\n }],\n [\"05_2_Resending_a_Transaction_with_RBF.md\",\n{\n 'v': 1372,\n 'f': \"1372\",\n }],\n [\"05_3_Funding_a_Transaction_with_CPFP.md\",\n{\n 'v': 827,\n 'f': \"827\",\n }],\n [\"06_0_Expanding_Bitcoin_Transactions_Multisigs.md\",\n{\n 'v': 155,\n 'f': \"155\",\n }],\n [\"06_1_Sending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1764,\n 'f': \"1764\",\n }],\n [\"06_2_Spending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1079,\n 'f': \"1079\",\n }],\n [\"06_3_Sending_an_Automated_Multisig.md\",\n{\n 'v': 613,\n 'f': \"613\",\n }],\n [\"07_0_Expanding_Bitcoin_Transactions_PSBTs.md\",\n{\n 'v': 169,\n 'f': \"169\",\n }],\n [\"07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1393,\n 'f': \"1393\",\n }],\n [\"07_3_Integrating_with_Hardware_Wallets.md\",\n{\n 'v': 2150,\n 'f': \"2150\",\n }],\n [\"08_0_Expanding_Bitcoin_Transactions_Other.md\",\n{\n 'v': 139,\n 'f': \"139\",\n }],\n [\"08_1_Sending_a_Transaction_with_a_Locktime.md\",\n{\n 'v': 1483,\n 'f': \"1483\",\n }],\n [\"08_2_Sending_a_Transaction_with_Data.md\",\n{\n 'v': 580,\n 'f': \"580\",\n }],\n [\"09_0_Introducing_Bitcoin_Scripts.md\",\n{\n 'v': 196,\n 'f': \"196\",\n }],\n [\"09_1_Understanding_the_Foundation_of_Transactions.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"09_2_Running_a_Bitcoin_Script.md\",\n{\n 'v': 863,\n 'f': \"863\",\n }],\n [\"09_3_Testing_a_Bitcoin_Script.md\",\n{\n 'v': 1000,\n 'f': \"1000\",\n }],\n [\"09_4_Scripting_a_P2PKH.md\",\n{\n 'v': 838,\n 'f': \"838\",\n }],\n [\"09_5_Scripting_a_P2WPKH.md\",\n{\n 'v': 845,\n 'f': \"845\",\n }],\n [\"10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md\",\n{\n 'v': 170,\n 'f': \"170\",\n }],\n [\"10_1_Understanding_the_Foundation_of_P2SH.md\",\n{\n 'v': 1164,\n 'f': \"1164\",\n }],\n [\"10_2_Building_the_Structure_of_P2SH.md\",\n{\n 'v': 1284,\n 'f': \"1284\",\n }],\n [\"10_3_Running_a_Bitcoin_Script_with_P2SH.md\",\n{\n 'v': 323,\n 'f': \"323\",\n }],\n [\"10_4_Scripting_a_Multisig.md\",\n{\n 'v': 1016,\n 'f': \"1016\",\n }],\n [\"10_5_Scripting_a_Segwit_Script.md\",\n{\n 'v': 750,\n 'f': \"750\",\n }],\n [\"10_6_Spending_a_P2SH_Transaction.md\",\n{\n 'v': 384,\n 'f': \"384\",\n }],\n [\"11_0_Empowering_Timelock_with_Bitcoin_Scripts.md\",\n{\n 'v': 108,\n 'f': \"108\",\n }],\n [\"11_1_Understanding_Timelock_Options.md\",\n{\n 'v': 557,\n 'f': \"557\",\n }],\n [\"11_2_Using_CLTV_in_Scripts.md\",\n{\n 'v': 1197,\n 'f': \"1197\",\n }],\n [\"11_3_Using_CSV_in_Scripts.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"12_0_Expanding_Bitcoin_Scripts.md\",\n{\n 'v': 99,\n 'f': \"99\",\n }],\n [\"12_1_Using_Script_Conditionals.md\",\n{\n 'v': 1120,\n 'f': \"1120\",\n }],\n [\"12_2_Using_Other_Script_Commands.md\",\n{\n 'v': 407,\n 'f': \"407\",\n }],\n [\"13_0_Designing_Real_Bitcoin_Scripts.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"13_1_Writing_Puzzle_Scripts.md\",\n{\n 'v': 998,\n 'f': \"998\",\n }],\n [\"13_2_Writing_Complex_Multisig_Scripts.md\",\n{\n 'v': 996,\n 'f': \"996\",\n }],\n [\"13_3_Empowering_Bitcoin_with_Scripts.md\",\n{\n 'v': 1467,\n 'f': \"1467\",\n }],\n [\"14_0_Using_Tor.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"14_1_Verifying_Your_Tor_Setup.md\",\n{\n 'v': 1568,\n 'f': \"1568\",\n }],\n [\"14_2_Changing_Your_Bitcoin_Hidden_Services.md\",\n{\n 'v': 434,\n 'f': \"434\",\n }],\n [\"14_3_Adding_SSH_Hidden_Services.md\",\n{\n 'v': 330,\n 'f': \"330\",\n }],\n [\"15_0_Talking_to_Bitcoind.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"15_1_Accessing_Bitcoind_with_C.md\",\n{\n 'v': 1238,\n 'f': \"1238\",\n }],\n [\"15_2_Programming_Bitcoind_with_C.md\",\n{\n 'v': 1427,\n 'f': \"1427\",\n }],\n [\"15_3_Receiving_Bitcoind_Notifications_with_C.md\",\n{\n 'v': 650,\n 'f': \"650\",\n }],\n [\"16_0_Programming_with_Libwally.md\",\n{\n 'v': 333,\n 'f': \"333\",\n }],\n [\"16_1_Setting_Up_Libwally.md\",\n{\n 'v': 559,\n 'f': \"559\",\n }],\n [\"16_2_Using_BIP39_in_Libwally.md\",\n{\n 'v': 939,\n 'f': \"939\",\n }],\n [\"16_3_Using_BIP32_in_Libwally.md\",\n{\n 'v': 959,\n 'f': \"959\",\n }],\n [\"16_4_Using_PSBTs_in_Libwally.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"16_5_Using_Scripts_in_Libwally.md\",\n{\n 'v': 785,\n 'f': \"785\",\n }],\n [\"16_6_Using_Other_Functions_in_Libwally.md\",\n{\n 'v': 655,\n 'f': \"655\",\n }],\n [\"16_7_Integrating_Libwally_and_Bitcoin-CLI.md\",\n{\n 'v': 1380,\n 'f': \"1380\",\n }],\n [\"17_0_Talking_to_Bitcoind_Other.md\",\n{\n 'v': 286,\n 'f': \"286\",\n }],\n [\"17_1_Accessing_Bitcoind_with_Go.md\",\n{\n 'v': 547,\n 'f': \"547\",\n }],\n [\"17_2_Accessing_Bitcoind_with_Java.md\",\n{\n 'v': 821,\n 'f': \"821\",\n }],\n [\"17_3_Accessing_Bitcoind_with_NodeJS.md\",\n{\n 'v': 393,\n 'f': \"393\",\n }],\n [\"17_4_Accessing_Bitcoind_with_Python.md\",\n{\n 'v': 1158,\n 'f': \"1158\",\n }],\n [\"17_5_Accessing_Bitcoind_with_Rust.md\",\n{\n 'v': 829,\n 'f': \"829\",\n }],\n [\"17_6_Accessing_Bitcoind_with_Swift.md\",\n{\n 'v': 1503,\n 'f': \"1503\",\n }],\n [\"18_0_Understanding_Your_Lightning_Setup.md\",\n{\n 'v': 192,\n 'f': \"192\",\n }],\n [\"18_1_Verifying_Your_Lightning_Setup.md\",\n{\n 'v': 1294,\n 'f': \"1294\",\n }],\n [\"18_2_Knowing_Your_lightning_Setup.md\",\n{\n 'v': 399,\n 'f': \"399\",\n }],\n [\"18_2__Interlude_Accessing_a_Second_Lightning_Node.md\",\n{\n 'v': 886,\n 'f': \"886\",\n }],\n [\"18_3_Setting_Up_a_Channel.md\",\n{\n 'v': 1173,\n 'f': \"1173\",\n }],\n [\"19_0_Using_Lightning.md\",\n{\n 'v': 146,\n 'f': \"146\",\n }],\n [\"19_1_Generate_a_Payment_Request.md\",\n{\n 'v': 968,\n 'f': \"968\",\n }],\n [\"19_2_Paying_a_Invoice.md\",\n{\n 'v': 604,\n 'f': \"604\",\n }],\n [\"19_3_Closing_a_Channel.md\",\n{\n 'v': 848,\n 'f': \"848\",\n }],\n [\"19_4_Lightning_Network_Review.md\",\n{\n 'v': 626,\n 'f': \"626\",\n }],\n [\"A0_Appendices.md\",\n{\n 'v': 112,\n 'f': \"112\",\n }],\n [\"A1_0_Understanding_Bitcoin_Standup.md\",\n{\n 'v': 420,\n 'f': \"420\",\n }],\n [\"A2_0_Compiling_Bitcoin_from_Source.md\",\n{\n 'v': 412,\n 'f': \"412\",\n }],\n [\"A3_0_Using_Bitcoin_Regtest.md\",\n{\n 'v': 980,\n 'f': \"980\",\n }],\n [\"CLA.md\",\n{\n 'v': 495,\n 'f': \"495\",\n }],\n [\"CONTRIBUTING.md\",\n{\n 'v': 529,\n 'f': \"529\",\n }],\n [\"LICENSE-CC-BY-4.0.md\",\n{\n 'v': 2716,\n 'f': \"2716\",\n }],\n [\"README.md\",\n{\n 'v': 1705,\n 'f': \"1705\",\n }],\n [\"TRANSLATING.md\",\n{\n 'v': 686,\n 'f': \"686\",\n }]],\n columns: [[\"string\", \"Chapter\"], [\"number\", \"Word Count\"]],\n columnOptions: [],\n rowsPerPage: 25,\n helpUrl: \"https://colab.research.google.com/notebooks/data_table.ipynb\",\n suppressOutputScrolling: true,\n minimumWidth: undefined,\n });\n ", + "text/plain": [ + "" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ChapterWord Count
6601_0_Introduction.md1144
6401_1_Introducing_Bitcoin.md2735
8202_0_Setting_Up_a_Bitcoin-Core_VPS.md226
7102_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackS...2746
5902_2_Setting_Up_Bitcoin_Core_Other.md254
.........
5CLA.md495
0CONTRIBUTING.md529
34LICENSE-CC-BY-4.0.md2716
29README.md1705
22TRANSLATING.md686
\n", + "

102 rows × 2 columns

\n", + "
" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 5 + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "14kdusmNzcfz" + }, + "source": [ + "To convert the table to a markdown format and save as 'Chapter_word_counts.md'" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uc7eKo9TkidD" + }, + "source": [ + "from IPython.display import Markdown, display\n", + "from tabulate import tabulate\n", + "\n", + "\n", + "# borrowed from https://stackoverflow.com/questions/33181846/programmatically-convert-pandas-dataframe-to-markdown-table\n", + "\n", + "def pandas_df_to_markdown_table(df):\n", + " fmt = ['---' for i in range(len(df.columns))]\n", + " df_fmt = pd.DataFrame([fmt], columns=df.columns)\n", + " df_formatted = pd.concat([df_fmt, df])\n", + " return Markdown(df_formatted.to_csv(sep=\"|\", index=False))\n", + "\n", + "def df_to_markdown(df, y_index=False):\n", + " blob = tabulate(df, headers='keys', tablefmt='pipe')\n", + " if not y_index:\n", + " return '\\n'.join(['| {}'.format(row.split('|', 2)[-1]) for row in blob.split('\\n')])\n", + " return blob" + ], + "execution_count": 6, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Y0QVAGKqzWX6" + }, + "source": [ + "mkdt = pandas_df_to_markdown_table(chapter_word_counts)\n", + "\n", + "with open('Chapter_word_counts.md', 'w') as m:\n", + " m.write(str(mkdt.data))" + ], + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "_gGsbGDckIrC", + "outputId": "8d4bbec6-aa6e-465b-fec7-4251f7f4cecf" + }, + "source": [ + "total_count_translatable = chapter_word_counts['Word Count'].sum()\n", + "total_count_translatable" + ], + "execution_count": 8, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "89069" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 8 + } + ] + } + ] +} \ No newline at end of file From 238d5b396db0b5753896f95d5e619813844e64b3 Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 22:17:13 -0500 Subject: [PATCH 08/50] Add files via upload --- Chapter_word_counts.md | 104 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 Chapter_word_counts.md diff --git a/Chapter_word_counts.md b/Chapter_word_counts.md new file mode 100644 index 0000000..ba0c304 --- /dev/null +++ b/Chapter_word_counts.md @@ -0,0 +1,104 @@ +Chapter|Word Count +---|--- +01_0_Introduction.md|1144 +01_1_Introducing_Bitcoin.md|2735 +02_0_Setting_Up_a_Bitcoin-Core_VPS.md|226 +02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md|2746 +02_2_Setting_Up_Bitcoin_Core_Other.md|254 +03_0_Understanding_Your_Bitcoin_Setup.md|248 +03_1_Verifying_Your_Bitcoin_Setup.md|773 +03_2_Knowing_Your_Bitcoin_Setup.md|517 +03_3_Setting_Up_Your_Wallet.md|1699 +03_3__Interlude_Using_Command-Line_Variables.md|347 +03_4_Receiving_a_Transaction.md|1479 +03_5_Understanding_the_Descriptor.md|1349 +04_0_Sending_Bitcoin_Transactions.md|176 +04_1_Sending_Coins_The_Easy_Way.md|1195 +04_2_Creating_a_Raw_Transaction.md|1720 +04_2__Interlude_Using_JQ.md|1956 +04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md|413 +04_4_Sending_Coins_with_a_Raw_Transaction.md|1024 +04_4__Interlude_Using_Curl.md|1643 +04_5_Sending_Coins_with_Automated_Raw_Transactions.md|614 +04_6_Creating_a_Segwit_Transaction.md|1172 +05_0_Controlling_Bitcoin_Transactions.md|149 +05_1_Watching_for_Stuck_Transactions.md|595 +05_2_Resending_a_Transaction_with_RBF.md|1372 +05_3_Funding_a_Transaction_with_CPFP.md|827 +06_0_Expanding_Bitcoin_Transactions_Multisigs.md|155 +06_1_Sending_a_Transaction_to_a_Multisig.md|1764 +06_2_Spending_a_Transaction_to_a_Multisig.md|1079 +06_3_Sending_an_Automated_Multisig.md|613 +07_0_Expanding_Bitcoin_Transactions_PSBTs.md|169 +07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md|1470 +07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md|1393 +07_3_Integrating_with_Hardware_Wallets.md|2150 +08_0_Expanding_Bitcoin_Transactions_Other.md|139 +08_1_Sending_a_Transaction_with_a_Locktime.md|1483 +08_2_Sending_a_Transaction_with_Data.md|580 +09_0_Introducing_Bitcoin_Scripts.md|196 +09_1_Understanding_the_Foundation_of_Transactions.md|989 +09_2_Running_a_Bitcoin_Script.md|863 +09_3_Testing_a_Bitcoin_Script.md|1000 +09_4_Scripting_a_P2PKH.md|838 +09_5_Scripting_a_P2WPKH.md|845 +10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md|170 +10_1_Understanding_the_Foundation_of_P2SH.md|1164 +10_2_Building_the_Structure_of_P2SH.md|1284 +10_3_Running_a_Bitcoin_Script_with_P2SH.md|323 +10_4_Scripting_a_Multisig.md|1016 +10_5_Scripting_a_Segwit_Script.md|750 +10_6_Spending_a_P2SH_Transaction.md|384 +11_0_Empowering_Timelock_with_Bitcoin_Scripts.md|108 +11_1_Understanding_Timelock_Options.md|557 +11_2_Using_CLTV_in_Scripts.md|1197 +11_3_Using_CSV_in_Scripts.md|1470 +12_0_Expanding_Bitcoin_Scripts.md|99 +12_1_Using_Script_Conditionals.md|1120 +12_2_Using_Other_Script_Commands.md|407 +13_0_Designing_Real_Bitcoin_Scripts.md|116 +13_1_Writing_Puzzle_Scripts.md|998 +13_2_Writing_Complex_Multisig_Scripts.md|996 +13_3_Empowering_Bitcoin_with_Scripts.md|1467 +14_0_Using_Tor.md|116 +14_1_Verifying_Your_Tor_Setup.md|1568 +14_2_Changing_Your_Bitcoin_Hidden_Services.md|434 +14_3_Adding_SSH_Hidden_Services.md|330 +15_0_Talking_to_Bitcoind.md|254 +15_1_Accessing_Bitcoind_with_C.md|1238 +15_2_Programming_Bitcoind_with_C.md|1427 +15_3_Receiving_Bitcoind_Notifications_with_C.md|650 +16_0_Programming_with_Libwally.md|333 +16_1_Setting_Up_Libwally.md|559 +16_2_Using_BIP39_in_Libwally.md|939 +16_3_Using_BIP32_in_Libwally.md|959 +16_4_Using_PSBTs_in_Libwally.md|989 +16_5_Using_Scripts_in_Libwally.md|785 +16_6_Using_Other_Functions_in_Libwally.md|655 +16_7_Integrating_Libwally_and_Bitcoin-CLI.md|1380 +17_0_Talking_to_Bitcoind_Other.md|286 +17_1_Accessing_Bitcoind_with_Go.md|547 +17_2_Accessing_Bitcoind_with_Java.md|821 +17_3_Accessing_Bitcoind_with_NodeJS.md|393 +17_4_Accessing_Bitcoind_with_Python.md|1158 +17_5_Accessing_Bitcoind_with_Rust.md|829 +17_6_Accessing_Bitcoind_with_Swift.md|1503 +18_0_Understanding_Your_Lightning_Setup.md|192 +18_1_Verifying_Your_Lightning_Setup.md|1294 +18_2_Knowing_Your_lightning_Setup.md|399 +18_2__Interlude_Accessing_a_Second_Lightning_Node.md|886 +18_3_Setting_Up_a_Channel.md|1173 +19_0_Using_Lightning.md|146 +19_1_Generate_a_Payment_Request.md|968 +19_2_Paying_a_Invoice.md|604 +19_3_Closing_a_Channel.md|848 +19_4_Lightning_Network_Review.md|626 +A0_Appendices.md|112 +A1_0_Understanding_Bitcoin_Standup.md|420 +A2_0_Compiling_Bitcoin_from_Source.md|412 +A3_0_Using_Bitcoin_Regtest.md|980 +CLA.md|495 +CONTRIBUTING.md|529 +LICENSE-CC-BY-4.0.md|2716 +README.md|1705 +TRANSLATING.md|686 From c5306f6885a165513f1f0b5381d3c19db609ca1e Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 22:39:48 -0500 Subject: [PATCH 09/50] Adding total to last row --- Chapter_word_counts.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Chapter_word_counts.md b/Chapter_word_counts.md index ba0c304..5f2bf3a 100644 --- a/Chapter_word_counts.md +++ b/Chapter_word_counts.md @@ -1,3 +1,4 @@ +## Translatable word counts by chapter Chapter|Word Count ---|--- 01_0_Introduction.md|1144 @@ -102,3 +103,4 @@ CONTRIBUTING.md|529 LICENSE-CC-BY-4.0.md|2716 README.md|1705 TRANSLATING.md|686 +TOTAL|89069 From 56ff02ee758ef791e3e5b9518ae567c116f456dd Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 22:41:11 -0500 Subject: [PATCH 10/50] Update Chapter_word_counts.md --- Chapter_word_counts.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Chapter_word_counts.md b/Chapter_word_counts.md index 5f2bf3a..4945dd2 100644 --- a/Chapter_word_counts.md +++ b/Chapter_word_counts.md @@ -1,4 +1,7 @@ ## Translatable word counts by chapter + +Ignores code blocks and other non-translateable characters + Chapter|Word Count ---|--- 01_0_Introduction.md|1144 From d33808e68ca8f89bda059c689740ee653e011c63 Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 22:47:31 -0500 Subject: [PATCH 11/50] Delete word_count_old.ipynb --- word_count_old.ipynb | 265 ------------------------------------------- 1 file changed, 265 deletions(-) delete mode 100644 word_count_old.ipynb diff --git a/word_count_old.ipynb b/word_count_old.ipynb deleted file mode 100644 index 62bd3e6..0000000 --- a/word_count_old.ipynb +++ /dev/null @@ -1,265 +0,0 @@ -{ - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "Untitled25.ipynb", - "provenance": [], - "authorship_tag": "ABX9TyMioTaWOtZ3dcIebltCT4IN", - "include_colab_link": true - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "view-in-github", - "colab_type": "text" - }, - "source": [ - "\"Open" - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "kT4wyWuy2szs" - }, - "source": [ - "import os\n", - "import pandas as pd" - ], - "execution_count": 1, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "9J62Uh4H2Y9g", - "outputId": "0ac3147d-fdb4-4b9c-d96b-4da334730a93" - }, - "source": [ - "!git clone https://github.com/icculp/Learning-Bitcoin-from-the-Command-Line.git" - ], - "execution_count": 2, - "outputs": [ - { - "output_type": "stream", - "text": [ - "Cloning into 'Learning-Bitcoin-from-the-Command-Line'...\n", - "remote: Enumerating objects: 6637, done.\u001b[K\n", - "remote: Counting objects: 100% (241/241), done.\u001b[K\n", - "remote: Compressing objects: 100% (199/199), done.\u001b[K\n", - "remote: Total 6637 (delta 110), reused 82 (delta 42), pack-reused 6396\u001b[K\n", - "Receiving objects: 100% (6637/6637), 7.53 MiB | 18.46 MiB/s, done.\n", - "Resolving deltas: 100% (4069/4069), done.\n" - ], - "name": "stdout" - } - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "k_g4-Fvn2yPy" - }, - "source": [ - "def count_words():\n", - " \"\"\" Counts words ignoring code blocks and digits \"\"\"\n", - " columns=['Chapter', 'Word Count']\n", - " counts = []\n", - " repo_path = '/content/Learning-Bitcoin-from-the-Command-Line/'\n", - " for chapter in os.listdir(repo_path):\n", - " if not chapter.endswith('.md'):\n", - " continue\n", - " count = 0\n", - " flag = 0 # ignores words between ``` code markdown\n", - " with open(repo_path + chapter) as ch:\n", - " for line in ch.readlines():\n", - " if flag:\n", - " if '```' in line:\n", - " flag = 0\n", - " continue\n", - " continue\n", - " if '```' in line:\n", - " flag = 1\n", - " continue\n", - " for word in line.split():\n", - " if any(ch.isdigit() for ch in word):\n", - " continue\n", - " count += 1\n", - " counts.append((chapter, count))\n", - " # print(chapter, count)\n", - " return pd.DataFrame(counts, columns=columns)" - ], - "execution_count": 3, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "id": "2-pkEaYF3Uxm" - }, - "source": [ - "chapter_word_counts = count_words()\n", - "chapter_word_counts.sort_values(by=['Chapter'], inplace=True)" - ], - "execution_count": 4, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 631 - }, - "id": "IPkG4oQJ6f1e", - "outputId": "eea2f4b6-c3d3-48b5-dc62-97885c18d48d" - }, - "source": [ - "from google.colab import data_table\n", - "data_table.DataTable(chapter_word_counts, include_index=False)" - ], - "execution_count": 5, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "application/vnd.google.colaboratory.module+javascript": "\n import \"https://ssl.gstatic.com/colaboratory/data_table/a6224c040fa35dcf/data_table.js\";\n\n window.createDataTable({\n data: [[\"01_0_Introduction.md\",\n{\n 'v': 1128,\n 'f': \"1128\",\n }],\n [\"01_1_Introducing_Bitcoin.md\",\n{\n 'v': 2784,\n 'f': \"2784\",\n }],\n [\"02_0_Setting_Up_a_Bitcoin-Core_VPS.md\",\n{\n 'v': 221,\n 'f': \"221\",\n }],\n [\"02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md\",\n{\n 'v': 1937,\n 'f': \"1937\",\n }],\n [\"02_2_Setting_Up_Bitcoin_Core_Other.md\",\n{\n 'v': 245,\n 'f': \"245\",\n }],\n [\"03_0_Understanding_Your_Bitcoin_Setup.md\",\n{\n 'v': 225,\n 'f': \"225\",\n }],\n [\"03_1_Verifying_Your_Bitcoin_Setup.md\",\n{\n 'v': 801,\n 'f': \"801\",\n }],\n [\"03_2_Knowing_Your_Bitcoin_Setup.md\",\n{\n 'v': 540,\n 'f': \"540\",\n }],\n [\"03_3_Setting_Up_Your_Wallet.md\",\n{\n 'v': 1741,\n 'f': \"1741\",\n }],\n [\"03_3__Interlude_Using_Command-Line_Variables.md\",\n{\n 'v': 354,\n 'f': \"354\",\n }],\n [\"03_4_Receiving_a_Transaction.md\",\n{\n 'v': 1521,\n 'f': \"1521\",\n }],\n [\"03_5_Understanding_the_Descriptor.md\",\n{\n 'v': 1393,\n 'f': \"1393\",\n }],\n [\"04_0_Sending_Bitcoin_Transactions.md\",\n{\n 'v': 153,\n 'f': \"153\",\n }],\n [\"04_1_Sending_Coins_The_Easy_Way.md\",\n{\n 'v': 1087,\n 'f': \"1087\",\n }],\n [\"04_2_Creating_a_Raw_Transaction.md\",\n{\n 'v': 1840,\n 'f': \"1840\",\n }],\n [\"04_2__Interlude_Using_JQ.md\",\n{\n 'v': 2034,\n 'f': \"2034\",\n }],\n [\"04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md\",\n{\n 'v': 428,\n 'f': \"428\",\n }],\n [\"04_4_Sending_Coins_with_a_Raw_Transaction.md\",\n{\n 'v': 1011,\n 'f': \"1011\",\n }],\n [\"04_4__Interlude_Using_Curl.md\",\n{\n 'v': 1247,\n 'f': \"1247\",\n }],\n [\"04_5_Sending_Coins_with_Automated_Raw_Transactions.md\",\n{\n 'v': 608,\n 'f': \"608\",\n }],\n [\"04_6_Creating_a_Segwit_Transaction.md\",\n{\n 'v': 1203,\n 'f': \"1203\",\n }],\n [\"05_0_Controlling_Bitcoin_Transactions.md\",\n{\n 'v': 144,\n 'f': \"144\",\n }],\n [\"05_1_Watching_for_Stuck_Transactions.md\",\n{\n 'v': 588,\n 'f': \"588\",\n }],\n [\"05_2_Resending_a_Transaction_with_RBF.md\",\n{\n 'v': 1412,\n 'f': \"1412\",\n }],\n [\"05_3_Funding_a_Transaction_with_CPFP.md\",\n{\n 'v': 846,\n 'f': \"846\",\n }],\n [\"06_0_Expanding_Bitcoin_Transactions_Multisigs.md\",\n{\n 'v': 148,\n 'f': \"148\",\n }],\n [\"06_1_Sending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1810,\n 'f': \"1810\",\n }],\n [\"06_2_Spending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1131,\n 'f': \"1131\",\n }],\n [\"06_3_Sending_an_Automated_Multisig.md\",\n{\n 'v': 625,\n 'f': \"625\",\n }],\n [\"07_0_Expanding_Bitcoin_Transactions_PSBTs.md\",\n{\n 'v': 163,\n 'f': \"163\",\n }],\n [\"07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1512,\n 'f': \"1512\",\n }],\n [\"07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1383,\n 'f': \"1383\",\n }],\n [\"07_3_Integrating_with_Hardware_Wallets.md\",\n{\n 'v': 2183,\n 'f': \"2183\",\n }],\n [\"08_0_Expanding_Bitcoin_Transactions_Other.md\",\n{\n 'v': 131,\n 'f': \"131\",\n }],\n [\"08_1_Sending_a_Transaction_with_a_Locktime.md\",\n{\n 'v': 1508,\n 'f': \"1508\",\n }],\n [\"08_2_Sending_a_Transaction_with_Data.md\",\n{\n 'v': 596,\n 'f': \"596\",\n }],\n [\"09_0_Introducing_Bitcoin_Scripts.md\",\n{\n 'v': 187,\n 'f': \"187\",\n }],\n [\"09_1_Understanding_the_Foundation_of_Transactions.md\",\n{\n 'v': 993,\n 'f': \"993\",\n }],\n [\"09_2_Running_a_Bitcoin_Script.md\",\n{\n 'v': 887,\n 'f': \"887\",\n }],\n [\"09_3_Testing_a_Bitcoin_Script.md\",\n{\n 'v': 1023,\n 'f': \"1023\",\n }],\n [\"09_4_Scripting_a_P2PKH.md\",\n{\n 'v': 889,\n 'f': \"889\",\n }],\n [\"09_5_Scripting_a_P2WPKH.md\",\n{\n 'v': 881,\n 'f': \"881\",\n }],\n [\"10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md\",\n{\n 'v': 152,\n 'f': \"152\",\n }],\n [\"10_1_Understanding_the_Foundation_of_P2SH.md\",\n{\n 'v': 1179,\n 'f': \"1179\",\n }],\n [\"10_2_Building_the_Structure_of_P2SH.md\",\n{\n 'v': 1318,\n 'f': \"1318\",\n }],\n [\"10_3_Running_a_Bitcoin_Script_with_P2SH.md\",\n{\n 'v': 340,\n 'f': \"340\",\n }],\n [\"10_4_Scripting_a_Multisig.md\",\n{\n 'v': 1043,\n 'f': \"1043\",\n }],\n [\"10_5_Scripting_a_Segwit_Script.md\",\n{\n 'v': 751,\n 'f': \"751\",\n }],\n [\"10_6_Spending_a_P2SH_Transaction.md\",\n{\n 'v': 393,\n 'f': \"393\",\n }],\n [\"11_0_Empowering_Timelock_with_Bitcoin_Scripts.md\",\n{\n 'v': 99,\n 'f': \"99\",\n }],\n [\"11_1_Understanding_Timelock_Options.md\",\n{\n 'v': 571,\n 'f': \"571\",\n }],\n [\"11_2_Using_CLTV_in_Scripts.md\",\n{\n 'v': 1241,\n 'f': \"1241\",\n }],\n [\"11_3_Using_CSV_in_Scripts.md\",\n{\n 'v': 1544,\n 'f': \"1544\",\n }],\n [\"12_0_Expanding_Bitcoin_Scripts.md\",\n{\n 'v': 99,\n 'f': \"99\",\n }],\n [\"12_1_Using_Script_Conditionals.md\",\n{\n 'v': 1216,\n 'f': \"1216\",\n }],\n [\"12_2_Using_Other_Script_Commands.md\",\n{\n 'v': 483,\n 'f': \"483\",\n }],\n [\"13_0_Designing_Real_Bitcoin_Scripts.md\",\n{\n 'v': 112,\n 'f': \"112\",\n }],\n [\"13_1_Writing_Puzzle_Scripts.md\",\n{\n 'v': 1032,\n 'f': \"1032\",\n }],\n [\"13_2_Writing_Complex_Multisig_Scripts.md\",\n{\n 'v': 1031,\n 'f': \"1031\",\n }],\n [\"13_3_Empowering_Bitcoin_with_Scripts.md\",\n{\n 'v': 1493,\n 'f': \"1493\",\n }],\n [\"14_0_Using_Tor.md\",\n{\n 'v': 110,\n 'f': \"110\",\n }],\n [\"14_1_Verifying_Your_Tor_Setup.md\",\n{\n 'v': 1632,\n 'f': \"1632\",\n }],\n [\"14_2_Changing_Your_Bitcoin_Hidden_Services.md\",\n{\n 'v': 460,\n 'f': \"460\",\n }],\n [\"14_3_Adding_SSH_Hidden_Services.md\",\n{\n 'v': 339,\n 'f': \"339\",\n }],\n [\"15_0_Talking_to_Bitcoind.md\",\n{\n 'v': 251,\n 'f': \"251\",\n }],\n [\"15_1_Accessing_Bitcoind_with_C.md\",\n{\n 'v': 1315,\n 'f': \"1315\",\n }],\n [\"15_2_Programming_Bitcoind_with_C.md\",\n{\n 'v': 1484,\n 'f': \"1484\",\n }],\n [\"15_3_Receiving_Bitcoind_Notifications_with_C.md\",\n{\n 'v': 669,\n 'f': \"669\",\n }],\n [\"16_0_Programming_with_Libwally.md\",\n{\n 'v': 317,\n 'f': \"317\",\n }],\n [\"16_1_Setting_Up_Libwally.md\",\n{\n 'v': 583,\n 'f': \"583\",\n }],\n [\"16_2_Using_BIP39_in_Libwally.md\",\n{\n 'v': 958,\n 'f': \"958\",\n }],\n [\"16_3_Using_BIP32_in_Libwally.md\",\n{\n 'v': 978,\n 'f': \"978\",\n }],\n [\"16_4_Using_PSBTs_in_Libwally.md\",\n{\n 'v': 1005,\n 'f': \"1005\",\n }],\n [\"16_5_Using_Scripts_in_Libwally.md\",\n{\n 'v': 789,\n 'f': \"789\",\n }],\n [\"16_6_Using_Other_Functions_in_Libwally.md\",\n{\n 'v': 746,\n 'f': \"746\",\n }],\n [\"16_7_Integrating_Libwally_and_Bitcoin-CLI.md\",\n{\n 'v': 1401,\n 'f': \"1401\",\n }],\n [\"17_0_Talking_to_Bitcoind_Other.md\",\n{\n 'v': 272,\n 'f': \"272\",\n }],\n [\"17_1_Accessing_Bitcoind_with_Go.md\",\n{\n 'v': 697,\n 'f': \"697\",\n }],\n [\"17_2_Accessing_Bitcoind_with_Java.md\",\n{\n 'v': 782,\n 'f': \"782\",\n }],\n [\"17_3_Accessing_Bitcoind_with_NodeJS.md\",\n{\n 'v': 476,\n 'f': \"476\",\n }],\n [\"17_4_Accessing_Bitcoind_with_Python.md\",\n{\n 'v': 1246,\n 'f': \"1246\",\n }],\n [\"17_5_Accessing_Bitcoind_with_Rust.md\",\n{\n 'v': 905,\n 'f': \"905\",\n }],\n [\"17_6_Accessing_Bitcoind_with_Swift.md\",\n{\n 'v': 1588,\n 'f': \"1588\",\n }],\n [\"18_0_Understanding_Your_Lightning_Setup.md\",\n{\n 'v': 185,\n 'f': \"185\",\n }],\n [\"18_1_Verifying_Your_Lightning_Setup.md\",\n{\n 'v': 1347,\n 'f': \"1347\",\n }],\n [\"18_2_Knowing_Your_lightning_Setup.md\",\n{\n 'v': 421,\n 'f': \"421\",\n }],\n [\"18_2__Interlude_Accessing_a_Second_Lightning_Node.md\",\n{\n 'v': 882,\n 'f': \"882\",\n }],\n [\"18_3_Setting_Up_a_Channel.md\",\n{\n 'v': 1219,\n 'f': \"1219\",\n }],\n [\"19_0_Using_Lightning.md\",\n{\n 'v': 145,\n 'f': \"145\",\n }],\n [\"19_1_Generate_a_Payment_Request.md\",\n{\n 'v': 995,\n 'f': \"995\",\n }],\n [\"19_2_Paying_a_Invoice.md\",\n{\n 'v': 614,\n 'f': \"614\",\n }],\n [\"19_3_Closing_a_Channel.md\",\n{\n 'v': 866,\n 'f': \"866\",\n }],\n [\"19_4_Lightning_Network_Review.md\",\n{\n 'v': 677,\n 'f': \"677\",\n }],\n [\"A0_Appendices.md\",\n{\n 'v': 110,\n 'f': \"110\",\n }],\n [\"A1_0_Understanding_Bitcoin_Standup.md\",\n{\n 'v': 412,\n 'f': \"412\",\n }],\n [\"A2_0_Compiling_Bitcoin_from_Source.md\",\n{\n 'v': 414,\n 'f': \"414\",\n }],\n [\"A3_0_Using_Bitcoin_Regtest.md\",\n{\n 'v': 995,\n 'f': \"995\",\n }],\n [\"CLA.md\",\n{\n 'v': 512,\n 'f': \"512\",\n }],\n [\"CONTRIBUTING.md\",\n{\n 'v': 555,\n 'f': \"555\",\n }],\n [\"LICENSE-CC-BY-4.0.md\",\n{\n 'v': 2734,\n 'f': \"2734\",\n }],\n [\"README.md\",\n{\n 'v': 1366,\n 'f': \"1366\",\n }],\n [\"TODO-30.md\",\n{\n 'v': 122,\n 'f': \"122\",\n }],\n [\"TODO.md\",\n{\n 'v': 734,\n 'f': \"734\",\n }]],\n columns: [[\"string\", \"Chapter\"], [\"number\", \"Word Count\"]],\n columnOptions: [],\n rowsPerPage: 25,\n helpUrl: \"https://colab.research.google.com/notebooks/data_table.ipynb\",\n suppressOutputScrolling: true,\n minimumWidth: undefined,\n });\n ", - "text/plain": [ - "" - ], - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ChapterWord Count
4401_0_Introduction.md1128
6901_1_Introducing_Bitcoin.md2784
9202_0_Setting_Up_a_Bitcoin-Core_VPS.md221
3302_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackS...1937
6602_2_Setting_Up_Bitcoin_Core_Other.md245
.........
45CONTRIBUTING.md555
34LICENSE-CC-BY-4.0.md2734
0README.md1366
52TODO-30.md122
29TODO.md734
\n", - "

103 rows × 2 columns

\n", - "
" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 5 - } - ] - }, - { - "cell_type": "code", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "4dFD792BBy0S", - "outputId": "3c4dc4ff-ceb3-4ff5-d40d-c606eec83a8c" - }, - "source": [ - "total_count = chapter_word_counts['Word Count'].sum()\n", - "total_count" - ], - "execution_count": 6, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "89946" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 6 - } - ] - } - ] -} From 77aa33b5f953df1060ccf439a06e8a18258feaae Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 22:48:42 -0500 Subject: [PATCH 12/50] Delete Chapter_word_count.ipynb --- Chapter_word_count.ipynb | 362 --------------------------------------- 1 file changed, 362 deletions(-) delete mode 100644 Chapter_word_count.ipynb diff --git a/Chapter_word_count.ipynb b/Chapter_word_count.ipynb deleted file mode 100644 index 8ce5aff..0000000 --- a/Chapter_word_count.ipynb +++ /dev/null @@ -1,362 +0,0 @@ -{ - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "Untitled25.ipynb", - "provenance": [], - "authorship_tag": "ABX9TyNJdlLdL56gLSWYqG177B0A", - "include_colab_link": true - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "view-in-github", - "colab_type": "text" - }, - "source": [ - "\"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "TQUe8ZZed-Bp" - }, - "source": [ - "Run in colab by clicking the link above to view the results as a paginated table with word counts for each chapter near the bottom of the notebook. Total word count at the very bottom." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "X7D8JEIgy9fV" - }, - "source": [ - "This notebook counts through the translatable words of each chapter, including chapter links; ignores code blocks, markdown characters, and tokens containing digits." - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "kT4wyWuy2szs" - }, - "source": [ - "import os\n", - "import pandas as pd\n", - "import re" - ], - "execution_count": 1, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "9J62Uh4H2Y9g", - "outputId": "8d2c4675-ddf9-4cd5-8fb2-ee4cae9b034d" - }, - "source": [ - "!git clone https://github.com/icculp/Learning-Bitcoin-from-the-Command-Line.git" - ], - "execution_count": 2, - "outputs": [ - { - "output_type": "stream", - "text": [ - "fatal: destination path 'Learning-Bitcoin-from-the-Command-Line' already exists and is not an empty directory.\n" - ], - "name": "stdout" - } - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "k_g4-Fvn2yPy" - }, - "source": [ - "def count_words():\n", - " \"\"\" Counts words ignoring code blocks and digits\n", - "\n", - " To test for quality:\n", - " lines 14-16 to test a single chapter\n", - " uncomment line 45 to view accepted word tokens\n", - " uncomment line \n", - " \"\"\"\n", - " columns=['Chapter', 'Word Count']\n", - " counts = []\n", - " repo_path = '/content/Learning-Bitcoin-from-the-Command-Line/'\n", - " for chapter in os.listdir(repo_path):\n", - " ''' uncomment lines 8-10 to test a single chapter, replacing ch_name\n", - " with the name you want to test\n", - " '''\n", - " #ch_name = '03_2_Knowing_Your_Bitcoin_Setup.md'\n", - " #if chapter != ch_name:\n", - " # continue\n", - " ignore_list = ['bitcoin.conf-annotated.txt', 'TODO.md', 'TODO-30.md']\n", - " if chapter in ignore_list or\\\n", - " not chapter.endswith('md'): # g\n", - " continue\n", - " count = 0\n", - " flag = 0 # ignores words between code markdown ```\n", - " with open(repo_path + chapter) as ch:\n", - " for line in ch.readlines():\n", - " if flag:\n", - " if '```' in line[:3].replace(' ', ''):\n", - " flag = 0\n", - " continue\n", - " continue\n", - " if '```' in line:\n", - " flag = 1\n", - " continue\n", - " for word in line.split():\n", - " if '.md' in word:\n", - " ch_link_tokens = word.split('_')\n", - " if ']' in word: # indicates trailing link with chapter name; counts last word of trailing link before chapter name\n", - " count += 1\n", - " link_tokens_count = len(ch_link_tokens[2:]) # ignoring chapter numbers in chapter link tokens\n", - " count += link_tokens_count\n", - " # print(word, '[TOK]', link_tokens_count, end='[SEPTOK]')\n", - " continue\n", - " ignore = ['*', '**', '#', '##', '###', '####',\n", - " '-', '—', '>', '`', '/', '&', '|', '~']\n", - " if any(ch.isdigit() for ch in word) or\\\n", - " word in ignore or\\\n", - " '`' in word or\\\n", - " '~/' in word or\\\n", - " '/.' in word or\\\n", - " '|-' in word or\\\n", - " (word[0] == ':' and word[-1] == ':') or\\\n", - " (word[0] == '\"' and word[-1] == '\"'):\n", - " # print(word) # , end='[SEP]') # view rejected tokens\n", - " continue\n", - " # print(word, count) # , end='[SEP]') # view accepted tokens\n", - " count += 1\n", - " counts.append((chapter, count))\n", - " # print(chapter, count)\n", - " return pd.DataFrame(counts, columns=columns)" - ], - "execution_count": 3, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "id": "2-pkEaYF3Uxm" - }, - "source": [ - "chapter_word_counts = count_words()\n", - "chapter_word_counts.sort_values(by=['Chapter'], inplace=True)\n", - "# view accepted or rejected tokens below if line 53 or 51 uncommented in count_words(), respectively" - ], - "execution_count": 4, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 631 - }, - "id": "K73GH7UFmwI5", - "outputId": "d1430339-8b1b-43f3-cdcf-1019948c7b9c" - }, - "source": [ - "from google.colab import data_table\n", - "data_table.DataTable(chapter_word_counts, include_index=False)" - ], - "execution_count": 5, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "application/vnd.google.colaboratory.module+javascript": "\n import \"https://ssl.gstatic.com/colaboratory/data_table/a6224c040fa35dcf/data_table.js\";\n\n window.createDataTable({\n data: [[\"01_0_Introduction.md\",\n{\n 'v': 1144,\n 'f': \"1144\",\n }],\n [\"01_1_Introducing_Bitcoin.md\",\n{\n 'v': 2735,\n 'f': \"2735\",\n }],\n [\"02_0_Setting_Up_a_Bitcoin-Core_VPS.md\",\n{\n 'v': 226,\n 'f': \"226\",\n }],\n [\"02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md\",\n{\n 'v': 2723,\n 'f': \"2723\",\n }],\n [\"02_2_Setting_Up_Bitcoin_Core_Other.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"03_0_Understanding_Your_Bitcoin_Setup.md\",\n{\n 'v': 248,\n 'f': \"248\",\n }],\n [\"03_1_Verifying_Your_Bitcoin_Setup.md\",\n{\n 'v': 773,\n 'f': \"773\",\n }],\n [\"03_2_Knowing_Your_Bitcoin_Setup.md\",\n{\n 'v': 517,\n 'f': \"517\",\n }],\n [\"03_3_Setting_Up_Your_Wallet.md\",\n{\n 'v': 1699,\n 'f': \"1699\",\n }],\n [\"03_3__Interlude_Using_Command-Line_Variables.md\",\n{\n 'v': 347,\n 'f': \"347\",\n }],\n [\"03_4_Receiving_a_Transaction.md\",\n{\n 'v': 1479,\n 'f': \"1479\",\n }],\n [\"03_5_Understanding_the_Descriptor.md\",\n{\n 'v': 1349,\n 'f': \"1349\",\n }],\n [\"04_0_Sending_Bitcoin_Transactions.md\",\n{\n 'v': 176,\n 'f': \"176\",\n }],\n [\"04_1_Sending_Coins_The_Easy_Way.md\",\n{\n 'v': 1068,\n 'f': \"1068\",\n }],\n [\"04_2_Creating_a_Raw_Transaction.md\",\n{\n 'v': 1720,\n 'f': \"1720\",\n }],\n [\"04_2__Interlude_Using_JQ.md\",\n{\n 'v': 1956,\n 'f': \"1956\",\n }],\n [\"04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md\",\n{\n 'v': 413,\n 'f': \"413\",\n }],\n [\"04_4_Sending_Coins_with_a_Raw_Transaction.md\",\n{\n 'v': 1024,\n 'f': \"1024\",\n }],\n [\"04_4__Interlude_Using_Curl.md\",\n{\n 'v': 1643,\n 'f': \"1643\",\n }],\n [\"04_5_Sending_Coins_with_Automated_Raw_Transactions.md\",\n{\n 'v': 614,\n 'f': \"614\",\n }],\n [\"04_6_Creating_a_Segwit_Transaction.md\",\n{\n 'v': 1172,\n 'f': \"1172\",\n }],\n [\"05_0_Controlling_Bitcoin_Transactions.md\",\n{\n 'v': 149,\n 'f': \"149\",\n }],\n [\"05_1_Watching_for_Stuck_Transactions.md\",\n{\n 'v': 595,\n 'f': \"595\",\n }],\n [\"05_2_Resending_a_Transaction_with_RBF.md\",\n{\n 'v': 1372,\n 'f': \"1372\",\n }],\n [\"05_3_Funding_a_Transaction_with_CPFP.md\",\n{\n 'v': 827,\n 'f': \"827\",\n }],\n [\"06_0_Expanding_Bitcoin_Transactions_Multisigs.md\",\n{\n 'v': 155,\n 'f': \"155\",\n }],\n [\"06_1_Sending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1764,\n 'f': \"1764\",\n }],\n [\"06_2_Spending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1079,\n 'f': \"1079\",\n }],\n [\"06_3_Sending_an_Automated_Multisig.md\",\n{\n 'v': 613,\n 'f': \"613\",\n }],\n [\"07_0_Expanding_Bitcoin_Transactions_PSBTs.md\",\n{\n 'v': 169,\n 'f': \"169\",\n }],\n [\"07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1393,\n 'f': \"1393\",\n }],\n [\"07_3_Integrating_with_Hardware_Wallets.md\",\n{\n 'v': 2150,\n 'f': \"2150\",\n }],\n [\"08_0_Expanding_Bitcoin_Transactions_Other.md\",\n{\n 'v': 139,\n 'f': \"139\",\n }],\n [\"08_1_Sending_a_Transaction_with_a_Locktime.md\",\n{\n 'v': 1483,\n 'f': \"1483\",\n }],\n [\"08_2_Sending_a_Transaction_with_Data.md\",\n{\n 'v': 580,\n 'f': \"580\",\n }],\n [\"09_0_Introducing_Bitcoin_Scripts.md\",\n{\n 'v': 196,\n 'f': \"196\",\n }],\n [\"09_1_Understanding_the_Foundation_of_Transactions.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"09_2_Running_a_Bitcoin_Script.md\",\n{\n 'v': 863,\n 'f': \"863\",\n }],\n [\"09_3_Testing_a_Bitcoin_Script.md\",\n{\n 'v': 1000,\n 'f': \"1000\",\n }],\n [\"09_4_Scripting_a_P2PKH.md\",\n{\n 'v': 838,\n 'f': \"838\",\n }],\n [\"09_5_Scripting_a_P2WPKH.md\",\n{\n 'v': 845,\n 'f': \"845\",\n }],\n [\"10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md\",\n{\n 'v': 170,\n 'f': \"170\",\n }],\n [\"10_1_Understanding_the_Foundation_of_P2SH.md\",\n{\n 'v': 1164,\n 'f': \"1164\",\n }],\n [\"10_2_Building_the_Structure_of_P2SH.md\",\n{\n 'v': 1284,\n 'f': \"1284\",\n }],\n [\"10_3_Running_a_Bitcoin_Script_with_P2SH.md\",\n{\n 'v': 323,\n 'f': \"323\",\n }],\n [\"10_4_Scripting_a_Multisig.md\",\n{\n 'v': 1016,\n 'f': \"1016\",\n }],\n [\"10_5_Scripting_a_Segwit_Script.md\",\n{\n 'v': 750,\n 'f': \"750\",\n }],\n [\"10_6_Spending_a_P2SH_Transaction.md\",\n{\n 'v': 384,\n 'f': \"384\",\n }],\n [\"11_0_Empowering_Timelock_with_Bitcoin_Scripts.md\",\n{\n 'v': 108,\n 'f': \"108\",\n }],\n [\"11_1_Understanding_Timelock_Options.md\",\n{\n 'v': 557,\n 'f': \"557\",\n }],\n [\"11_2_Using_CLTV_in_Scripts.md\",\n{\n 'v': 1197,\n 'f': \"1197\",\n }],\n [\"11_3_Using_CSV_in_Scripts.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"12_0_Expanding_Bitcoin_Scripts.md\",\n{\n 'v': 99,\n 'f': \"99\",\n }],\n [\"12_1_Using_Script_Conditionals.md\",\n{\n 'v': 1120,\n 'f': \"1120\",\n }],\n [\"12_2_Using_Other_Script_Commands.md\",\n{\n 'v': 407,\n 'f': \"407\",\n }],\n [\"13_0_Designing_Real_Bitcoin_Scripts.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"13_1_Writing_Puzzle_Scripts.md\",\n{\n 'v': 998,\n 'f': \"998\",\n }],\n [\"13_2_Writing_Complex_Multisig_Scripts.md\",\n{\n 'v': 996,\n 'f': \"996\",\n }],\n [\"13_3_Empowering_Bitcoin_with_Scripts.md\",\n{\n 'v': 1467,\n 'f': \"1467\",\n }],\n [\"14_0_Using_Tor.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"14_1_Verifying_Your_Tor_Setup.md\",\n{\n 'v': 1568,\n 'f': \"1568\",\n }],\n [\"14_2_Changing_Your_Bitcoin_Hidden_Services.md\",\n{\n 'v': 434,\n 'f': \"434\",\n }],\n [\"14_3_Adding_SSH_Hidden_Services.md\",\n{\n 'v': 330,\n 'f': \"330\",\n }],\n [\"15_0_Talking_to_Bitcoind.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"15_1_Accessing_Bitcoind_with_C.md\",\n{\n 'v': 1238,\n 'f': \"1238\",\n }],\n [\"15_2_Programming_Bitcoind_with_C.md\",\n{\n 'v': 1427,\n 'f': \"1427\",\n }],\n [\"15_3_Receiving_Bitcoind_Notifications_with_C.md\",\n{\n 'v': 650,\n 'f': \"650\",\n }],\n [\"16_0_Programming_with_Libwally.md\",\n{\n 'v': 333,\n 'f': \"333\",\n }],\n [\"16_1_Setting_Up_Libwally.md\",\n{\n 'v': 559,\n 'f': \"559\",\n }],\n [\"16_2_Using_BIP39_in_Libwally.md\",\n{\n 'v': 939,\n 'f': \"939\",\n }],\n [\"16_3_Using_BIP32_in_Libwally.md\",\n{\n 'v': 959,\n 'f': \"959\",\n }],\n [\"16_4_Using_PSBTs_in_Libwally.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"16_5_Using_Scripts_in_Libwally.md\",\n{\n 'v': 785,\n 'f': \"785\",\n }],\n [\"16_6_Using_Other_Functions_in_Libwally.md\",\n{\n 'v': 655,\n 'f': \"655\",\n }],\n [\"16_7_Integrating_Libwally_and_Bitcoin-CLI.md\",\n{\n 'v': 1380,\n 'f': \"1380\",\n }],\n [\"17_0_Talking_to_Bitcoind_Other.md\",\n{\n 'v': 286,\n 'f': \"286\",\n }],\n [\"17_1_Accessing_Bitcoind_with_Go.md\",\n{\n 'v': 547,\n 'f': \"547\",\n }],\n [\"17_2_Accessing_Bitcoind_with_Java.md\",\n{\n 'v': 821,\n 'f': \"821\",\n }],\n [\"17_3_Accessing_Bitcoind_with_NodeJS.md\",\n{\n 'v': 393,\n 'f': \"393\",\n }],\n [\"17_4_Accessing_Bitcoind_with_Python.md\",\n{\n 'v': 1158,\n 'f': \"1158\",\n }],\n [\"17_5_Accessing_Bitcoind_with_Rust.md\",\n{\n 'v': 829,\n 'f': \"829\",\n }],\n [\"17_6_Accessing_Bitcoind_with_Swift.md\",\n{\n 'v': 1503,\n 'f': \"1503\",\n }],\n [\"18_0_Understanding_Your_Lightning_Setup.md\",\n{\n 'v': 192,\n 'f': \"192\",\n }],\n [\"18_1_Verifying_Your_Lightning_Setup.md\",\n{\n 'v': 1294,\n 'f': \"1294\",\n }],\n [\"18_2_Knowing_Your_lightning_Setup.md\",\n{\n 'v': 399,\n 'f': \"399\",\n }],\n [\"18_2__Interlude_Accessing_a_Second_Lightning_Node.md\",\n{\n 'v': 886,\n 'f': \"886\",\n }],\n [\"18_3_Setting_Up_a_Channel.md\",\n{\n 'v': 1173,\n 'f': \"1173\",\n }],\n [\"19_0_Using_Lightning.md\",\n{\n 'v': 146,\n 'f': \"146\",\n }],\n [\"19_1_Generate_a_Payment_Request.md\",\n{\n 'v': 968,\n 'f': \"968\",\n }],\n [\"19_2_Paying_a_Invoice.md\",\n{\n 'v': 604,\n 'f': \"604\",\n }],\n [\"19_3_Closing_a_Channel.md\",\n{\n 'v': 848,\n 'f': \"848\",\n }],\n [\"19_4_Lightning_Network_Review.md\",\n{\n 'v': 626,\n 'f': \"626\",\n }],\n [\"A0_Appendices.md\",\n{\n 'v': 112,\n 'f': \"112\",\n }],\n [\"A1_0_Understanding_Bitcoin_Standup.md\",\n{\n 'v': 420,\n 'f': \"420\",\n }],\n [\"A2_0_Compiling_Bitcoin_from_Source.md\",\n{\n 'v': 412,\n 'f': \"412\",\n }],\n [\"A3_0_Using_Bitcoin_Regtest.md\",\n{\n 'v': 980,\n 'f': \"980\",\n }],\n [\"CLA.md\",\n{\n 'v': 495,\n 'f': \"495\",\n }],\n [\"CONTRIBUTING.md\",\n{\n 'v': 529,\n 'f': \"529\",\n }],\n [\"LICENSE-CC-BY-4.0.md\",\n{\n 'v': 2716,\n 'f': \"2716\",\n }],\n [\"README.md\",\n{\n 'v': 1687,\n 'f': \"1687\",\n }]],\n columns: [[\"string\", \"Chapter\"], [\"number\", \"Word Count\"]],\n columnOptions: [],\n rowsPerPage: 25,\n helpUrl: \"https://colab.research.google.com/notebooks/data_table.ipynb\",\n suppressOutputScrolling: true,\n minimumWidth: undefined,\n });\n ", - "text/plain": [ - "" - ], - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ChapterWord Count
7201_0_Introduction.md1144
2101_1_Introducing_Bitcoin.md2735
2002_0_Setting_Up_a_Bitcoin-Core_VPS.md226
9702_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackS...2723
9402_2_Setting_Up_Bitcoin_Core_Other.md254
.........
45A3_0_Using_Bitcoin_Regtest.md980
38CLA.md495
74CONTRIBUTING.md529
53LICENSE-CC-BY-4.0.md2716
2README.md1687
\n", - "

101 rows × 2 columns

\n", - "
" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 5 - } - ] - }, - { - "cell_type": "code", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "_gGsbGDckIrC", - "outputId": "a9811107-2a07-464a-d96a-c6767e5ea7d4" - }, - "source": [ - "total_count = chapter_word_counts['Word Count'].sum()\n", - "total_count" - ], - "execution_count": 6, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "88215" - ] - }, - "metadata": { - "tags": [] - }, - "execution_count": 6 - } - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "14kdusmNzcfz" - }, - "source": [ - "To convert the table to a markdown format and save as 'Chapter_word_counts.md', run the cells below" - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "uc7eKo9TkidD" - }, - "source": [ - "from IPython.display import Markdown, display\n", - "from tabulate import tabulate\n", - "\n", - "\n", - "# borrowed from https://stackoverflow.com/questions/33181846/programmatically-convert-pandas-dataframe-to-markdown-table\n", - "\n", - "def pandas_df_to_markdown_table(df):\n", - " fmt = ['---' for i in range(len(df.columns))]\n", - " df_fmt = pd.DataFrame([fmt], columns=df.columns)\n", - " df_formatted = pd.concat([df_fmt, df])\n", - " return Markdown(df_formatted.to_csv(sep=\"|\", index=False))\n", - "\n", - "def df_to_markdown(df, y_index=False):\n", - " blob = tabulate(df, headers='keys', tablefmt='pipe')\n", - " if not y_index:\n", - " return '\\n'.join(['| {}'.format(row.split('|', 2)[-1]) for row in blob.split('\\n')])\n", - " return blob" - ], - "execution_count": 7, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "id": "Y0QVAGKqzWX6" - }, - "source": [ - "mkt = pandas_df_to_markdown_table(chapter_word_counts)\n", - "\n", - "with open('Chapter_word_counts.md', 'w') as m:\n", - " m.write(str(mkt.data))" - ], - "execution_count": 8, - "outputs": [] - } - ] -} \ No newline at end of file From 9916b65adc48317826ff1e82b744327fa497c8de Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 23:02:24 -0500 Subject: [PATCH 13/50] Adding total to dataframe --- Chapter_word_counts.ipynb | 71 ++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/Chapter_word_counts.ipynb b/Chapter_word_counts.ipynb index e404454..0c85721 100644 --- a/Chapter_word_counts.ipynb +++ b/Chapter_word_counts.ipynb @@ -5,7 +5,7 @@ "colab": { "name": "Untitled25.ipynb", "provenance": [], - "authorship_tag": "ABX9TyNHQ/J52I0G+daf1wNCNdAI", + "authorship_tag": "ABX9TyMjw6y4q6XdjW6h80beORDK", "include_colab_link": true }, "kernelspec": { @@ -33,7 +33,7 @@ "id": "X7D8JEIgy9fV" }, "source": [ - "This notebook counts through the translatable words of each chapter, including chapter links; ignores code blocks, markdown characters, and tokens containing digits." + "This notebook counts through the translatable words of each chapter, including chapter links; ignores code blocks, markdown characters, and other non-translatable characters." ] }, { @@ -42,7 +42,7 @@ "id": "TQUe8ZZed-Bp" }, "source": [ - "Run in colab by clicking the link above to view the results as a paginated table with word counts for each chapter near the bottom of the notebook. Total word count at the very bottom." + "Run in colab by clicking the link above to view the results as a paginated table with word counts for each chapter near the bottom of the notebook. Total word count at the very bottom. Markdown friendly table created in Chapter_word_counts.md" ] }, { @@ -64,10 +64,10 @@ "base_uri": "https://localhost:8080/" }, "id": "9J62Uh4H2Y9g", - "outputId": "3295f8b2-5255-4eac-bc78-3da247037c41" + "outputId": "05d36385-659c-4f88-a82c-6dd877efd645" }, "source": [ - "!git clone https://github.com/icculp/Learning-Bitcoin-from-the-Command-Line.git" + "!git clone https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line.git" ], "execution_count": 2, "outputs": [ @@ -75,12 +75,12 @@ "output_type": "stream", "text": [ "Cloning into 'Learning-Bitcoin-from-the-Command-Line'...\n", - "remote: Enumerating objects: 6715, done.\u001b[K\n", - "remote: Counting objects: 100% (319/319), done.\u001b[K\n", - "remote: Compressing objects: 100% (193/193), done.\u001b[K\n", - "remote: Total 6715 (delta 157), reused 277 (delta 125), pack-reused 6396\u001b[K\n", - "Receiving objects: 100% (6715/6715), 7.56 MiB | 22.84 MiB/s, done.\n", - "Resolving deltas: 100% (4116/4116), done.\n" + "remote: Enumerating objects: 6705, done.\u001b[K\n", + "remote: Counting objects: 100% (309/309), done.\u001b[K\n", + "remote: Compressing objects: 100% (192/192), done.\u001b[K\n", + "remote: Total 6705 (delta 147), reused 267 (delta 112), pack-reused 6396\u001b[K\n", + "Receiving objects: 100% (6705/6705), 7.55 MiB | 25.61 MiB/s, done.\n", + "Resolving deltas: 100% (4106/4106), done.\n" ], "name": "stdout" } @@ -164,12 +164,24 @@ }, "source": [ "chapter_word_counts = count_words()\n", - "chapter_word_counts.sort_values(by=['Chapter'], inplace=True)\n", "# view accepted or rejected tokens below if line 55 or 53 uncommented in count_words(), respectively" ], "execution_count": 4, "outputs": [] }, + { + "cell_type": "code", + "metadata": { + "id": "Tc9IsNpC-vwR" + }, + "source": [ + "chapter_word_counts.sort_values(by=['Chapter'], inplace=True)\n", + "total_count_translatable = chapter_word_counts['Word Count'].sum()\n", + "chapter_word_counts.loc[len(chapter_word_counts.index)] = ['TOTAL', total_count_translatable] " + ], + "execution_count": 5, + "outputs": [] + }, { "cell_type": "markdown", "metadata": { @@ -187,18 +199,18 @@ "height": 631 }, "id": "K73GH7UFmwI5", - "outputId": "246c0b17-0854-4811-c67f-8081d7950272" + "outputId": "a4361d36-caf3-4bb7-ac6d-4cdc71f49afc" }, "source": [ "from google.colab import data_table\n", "data_table.DataTable(chapter_word_counts, include_index=False)" ], - "execution_count": 5, + "execution_count": 6, "outputs": [ { "output_type": "execute_result", "data": { - "application/vnd.google.colaboratory.module+javascript": "\n import \"https://ssl.gstatic.com/colaboratory/data_table/a6224c040fa35dcf/data_table.js\";\n\n window.createDataTable({\n data: [[\"01_0_Introduction.md\",\n{\n 'v': 1144,\n 'f': \"1144\",\n }],\n [\"01_1_Introducing_Bitcoin.md\",\n{\n 'v': 2735,\n 'f': \"2735\",\n }],\n [\"02_0_Setting_Up_a_Bitcoin-Core_VPS.md\",\n{\n 'v': 226,\n 'f': \"226\",\n }],\n [\"02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md\",\n{\n 'v': 2746,\n 'f': \"2746\",\n }],\n [\"02_2_Setting_Up_Bitcoin_Core_Other.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"03_0_Understanding_Your_Bitcoin_Setup.md\",\n{\n 'v': 248,\n 'f': \"248\",\n }],\n [\"03_1_Verifying_Your_Bitcoin_Setup.md\",\n{\n 'v': 773,\n 'f': \"773\",\n }],\n [\"03_2_Knowing_Your_Bitcoin_Setup.md\",\n{\n 'v': 517,\n 'f': \"517\",\n }],\n [\"03_3_Setting_Up_Your_Wallet.md\",\n{\n 'v': 1699,\n 'f': \"1699\",\n }],\n [\"03_3__Interlude_Using_Command-Line_Variables.md\",\n{\n 'v': 347,\n 'f': \"347\",\n }],\n [\"03_4_Receiving_a_Transaction.md\",\n{\n 'v': 1479,\n 'f': \"1479\",\n }],\n [\"03_5_Understanding_the_Descriptor.md\",\n{\n 'v': 1349,\n 'f': \"1349\",\n }],\n [\"04_0_Sending_Bitcoin_Transactions.md\",\n{\n 'v': 176,\n 'f': \"176\",\n }],\n [\"04_1_Sending_Coins_The_Easy_Way.md\",\n{\n 'v': 1195,\n 'f': \"1195\",\n }],\n [\"04_2_Creating_a_Raw_Transaction.md\",\n{\n 'v': 1720,\n 'f': \"1720\",\n }],\n [\"04_2__Interlude_Using_JQ.md\",\n{\n 'v': 1956,\n 'f': \"1956\",\n }],\n [\"04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md\",\n{\n 'v': 413,\n 'f': \"413\",\n }],\n [\"04_4_Sending_Coins_with_a_Raw_Transaction.md\",\n{\n 'v': 1024,\n 'f': \"1024\",\n }],\n [\"04_4__Interlude_Using_Curl.md\",\n{\n 'v': 1643,\n 'f': \"1643\",\n }],\n [\"04_5_Sending_Coins_with_Automated_Raw_Transactions.md\",\n{\n 'v': 614,\n 'f': \"614\",\n }],\n [\"04_6_Creating_a_Segwit_Transaction.md\",\n{\n 'v': 1172,\n 'f': \"1172\",\n }],\n [\"05_0_Controlling_Bitcoin_Transactions.md\",\n{\n 'v': 149,\n 'f': \"149\",\n }],\n [\"05_1_Watching_for_Stuck_Transactions.md\",\n{\n 'v': 595,\n 'f': \"595\",\n }],\n [\"05_2_Resending_a_Transaction_with_RBF.md\",\n{\n 'v': 1372,\n 'f': \"1372\",\n }],\n [\"05_3_Funding_a_Transaction_with_CPFP.md\",\n{\n 'v': 827,\n 'f': \"827\",\n }],\n [\"06_0_Expanding_Bitcoin_Transactions_Multisigs.md\",\n{\n 'v': 155,\n 'f': \"155\",\n }],\n [\"06_1_Sending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1764,\n 'f': \"1764\",\n }],\n [\"06_2_Spending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1079,\n 'f': \"1079\",\n }],\n [\"06_3_Sending_an_Automated_Multisig.md\",\n{\n 'v': 613,\n 'f': \"613\",\n }],\n [\"07_0_Expanding_Bitcoin_Transactions_PSBTs.md\",\n{\n 'v': 169,\n 'f': \"169\",\n }],\n [\"07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1393,\n 'f': \"1393\",\n }],\n [\"07_3_Integrating_with_Hardware_Wallets.md\",\n{\n 'v': 2150,\n 'f': \"2150\",\n }],\n [\"08_0_Expanding_Bitcoin_Transactions_Other.md\",\n{\n 'v': 139,\n 'f': \"139\",\n }],\n [\"08_1_Sending_a_Transaction_with_a_Locktime.md\",\n{\n 'v': 1483,\n 'f': \"1483\",\n }],\n [\"08_2_Sending_a_Transaction_with_Data.md\",\n{\n 'v': 580,\n 'f': \"580\",\n }],\n [\"09_0_Introducing_Bitcoin_Scripts.md\",\n{\n 'v': 196,\n 'f': \"196\",\n }],\n [\"09_1_Understanding_the_Foundation_of_Transactions.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"09_2_Running_a_Bitcoin_Script.md\",\n{\n 'v': 863,\n 'f': \"863\",\n }],\n [\"09_3_Testing_a_Bitcoin_Script.md\",\n{\n 'v': 1000,\n 'f': \"1000\",\n }],\n [\"09_4_Scripting_a_P2PKH.md\",\n{\n 'v': 838,\n 'f': \"838\",\n }],\n [\"09_5_Scripting_a_P2WPKH.md\",\n{\n 'v': 845,\n 'f': \"845\",\n }],\n [\"10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md\",\n{\n 'v': 170,\n 'f': \"170\",\n }],\n [\"10_1_Understanding_the_Foundation_of_P2SH.md\",\n{\n 'v': 1164,\n 'f': \"1164\",\n }],\n [\"10_2_Building_the_Structure_of_P2SH.md\",\n{\n 'v': 1284,\n 'f': \"1284\",\n }],\n [\"10_3_Running_a_Bitcoin_Script_with_P2SH.md\",\n{\n 'v': 323,\n 'f': \"323\",\n }],\n [\"10_4_Scripting_a_Multisig.md\",\n{\n 'v': 1016,\n 'f': \"1016\",\n }],\n [\"10_5_Scripting_a_Segwit_Script.md\",\n{\n 'v': 750,\n 'f': \"750\",\n }],\n [\"10_6_Spending_a_P2SH_Transaction.md\",\n{\n 'v': 384,\n 'f': \"384\",\n }],\n [\"11_0_Empowering_Timelock_with_Bitcoin_Scripts.md\",\n{\n 'v': 108,\n 'f': \"108\",\n }],\n [\"11_1_Understanding_Timelock_Options.md\",\n{\n 'v': 557,\n 'f': \"557\",\n }],\n [\"11_2_Using_CLTV_in_Scripts.md\",\n{\n 'v': 1197,\n 'f': \"1197\",\n }],\n [\"11_3_Using_CSV_in_Scripts.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"12_0_Expanding_Bitcoin_Scripts.md\",\n{\n 'v': 99,\n 'f': \"99\",\n }],\n [\"12_1_Using_Script_Conditionals.md\",\n{\n 'v': 1120,\n 'f': \"1120\",\n }],\n [\"12_2_Using_Other_Script_Commands.md\",\n{\n 'v': 407,\n 'f': \"407\",\n }],\n [\"13_0_Designing_Real_Bitcoin_Scripts.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"13_1_Writing_Puzzle_Scripts.md\",\n{\n 'v': 998,\n 'f': \"998\",\n }],\n [\"13_2_Writing_Complex_Multisig_Scripts.md\",\n{\n 'v': 996,\n 'f': \"996\",\n }],\n [\"13_3_Empowering_Bitcoin_with_Scripts.md\",\n{\n 'v': 1467,\n 'f': \"1467\",\n }],\n [\"14_0_Using_Tor.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"14_1_Verifying_Your_Tor_Setup.md\",\n{\n 'v': 1568,\n 'f': \"1568\",\n }],\n [\"14_2_Changing_Your_Bitcoin_Hidden_Services.md\",\n{\n 'v': 434,\n 'f': \"434\",\n }],\n [\"14_3_Adding_SSH_Hidden_Services.md\",\n{\n 'v': 330,\n 'f': \"330\",\n }],\n [\"15_0_Talking_to_Bitcoind.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"15_1_Accessing_Bitcoind_with_C.md\",\n{\n 'v': 1238,\n 'f': \"1238\",\n }],\n [\"15_2_Programming_Bitcoind_with_C.md\",\n{\n 'v': 1427,\n 'f': \"1427\",\n }],\n [\"15_3_Receiving_Bitcoind_Notifications_with_C.md\",\n{\n 'v': 650,\n 'f': \"650\",\n }],\n [\"16_0_Programming_with_Libwally.md\",\n{\n 'v': 333,\n 'f': \"333\",\n }],\n [\"16_1_Setting_Up_Libwally.md\",\n{\n 'v': 559,\n 'f': \"559\",\n }],\n [\"16_2_Using_BIP39_in_Libwally.md\",\n{\n 'v': 939,\n 'f': \"939\",\n }],\n [\"16_3_Using_BIP32_in_Libwally.md\",\n{\n 'v': 959,\n 'f': \"959\",\n }],\n [\"16_4_Using_PSBTs_in_Libwally.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"16_5_Using_Scripts_in_Libwally.md\",\n{\n 'v': 785,\n 'f': \"785\",\n }],\n [\"16_6_Using_Other_Functions_in_Libwally.md\",\n{\n 'v': 655,\n 'f': \"655\",\n }],\n [\"16_7_Integrating_Libwally_and_Bitcoin-CLI.md\",\n{\n 'v': 1380,\n 'f': \"1380\",\n }],\n [\"17_0_Talking_to_Bitcoind_Other.md\",\n{\n 'v': 286,\n 'f': \"286\",\n }],\n [\"17_1_Accessing_Bitcoind_with_Go.md\",\n{\n 'v': 547,\n 'f': \"547\",\n }],\n [\"17_2_Accessing_Bitcoind_with_Java.md\",\n{\n 'v': 821,\n 'f': \"821\",\n }],\n [\"17_3_Accessing_Bitcoind_with_NodeJS.md\",\n{\n 'v': 393,\n 'f': \"393\",\n }],\n [\"17_4_Accessing_Bitcoind_with_Python.md\",\n{\n 'v': 1158,\n 'f': \"1158\",\n }],\n [\"17_5_Accessing_Bitcoind_with_Rust.md\",\n{\n 'v': 829,\n 'f': \"829\",\n }],\n [\"17_6_Accessing_Bitcoind_with_Swift.md\",\n{\n 'v': 1503,\n 'f': \"1503\",\n }],\n [\"18_0_Understanding_Your_Lightning_Setup.md\",\n{\n 'v': 192,\n 'f': \"192\",\n }],\n [\"18_1_Verifying_Your_Lightning_Setup.md\",\n{\n 'v': 1294,\n 'f': \"1294\",\n }],\n [\"18_2_Knowing_Your_lightning_Setup.md\",\n{\n 'v': 399,\n 'f': \"399\",\n }],\n [\"18_2__Interlude_Accessing_a_Second_Lightning_Node.md\",\n{\n 'v': 886,\n 'f': \"886\",\n }],\n [\"18_3_Setting_Up_a_Channel.md\",\n{\n 'v': 1173,\n 'f': \"1173\",\n }],\n [\"19_0_Using_Lightning.md\",\n{\n 'v': 146,\n 'f': \"146\",\n }],\n [\"19_1_Generate_a_Payment_Request.md\",\n{\n 'v': 968,\n 'f': \"968\",\n }],\n [\"19_2_Paying_a_Invoice.md\",\n{\n 'v': 604,\n 'f': \"604\",\n }],\n [\"19_3_Closing_a_Channel.md\",\n{\n 'v': 848,\n 'f': \"848\",\n }],\n [\"19_4_Lightning_Network_Review.md\",\n{\n 'v': 626,\n 'f': \"626\",\n }],\n [\"A0_Appendices.md\",\n{\n 'v': 112,\n 'f': \"112\",\n }],\n [\"A1_0_Understanding_Bitcoin_Standup.md\",\n{\n 'v': 420,\n 'f': \"420\",\n }],\n [\"A2_0_Compiling_Bitcoin_from_Source.md\",\n{\n 'v': 412,\n 'f': \"412\",\n }],\n [\"A3_0_Using_Bitcoin_Regtest.md\",\n{\n 'v': 980,\n 'f': \"980\",\n }],\n [\"CLA.md\",\n{\n 'v': 495,\n 'f': \"495\",\n }],\n [\"CONTRIBUTING.md\",\n{\n 'v': 529,\n 'f': \"529\",\n }],\n [\"LICENSE-CC-BY-4.0.md\",\n{\n 'v': 2716,\n 'f': \"2716\",\n }],\n [\"README.md\",\n{\n 'v': 1705,\n 'f': \"1705\",\n }],\n [\"TRANSLATING.md\",\n{\n 'v': 686,\n 'f': \"686\",\n }]],\n columns: [[\"string\", \"Chapter\"], [\"number\", \"Word Count\"]],\n columnOptions: [],\n rowsPerPage: 25,\n helpUrl: \"https://colab.research.google.com/notebooks/data_table.ipynb\",\n suppressOutputScrolling: true,\n minimumWidth: undefined,\n });\n ", + "application/vnd.google.colaboratory.module+javascript": "\n import \"https://ssl.gstatic.com/colaboratory/data_table/a6224c040fa35dcf/data_table.js\";\n\n window.createDataTable({\n data: [[\"01_0_Introduction.md\",\n{\n 'v': 1144,\n 'f': \"1144\",\n }],\n [\"01_1_Introducing_Bitcoin.md\",\n{\n 'v': 2735,\n 'f': \"2735\",\n }],\n [\"02_0_Setting_Up_a_Bitcoin-Core_VPS.md\",\n{\n 'v': 226,\n 'f': \"226\",\n }],\n [\"02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md\",\n{\n 'v': 2746,\n 'f': \"2746\",\n }],\n [\"02_2_Setting_Up_Bitcoin_Core_Other.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"03_0_Understanding_Your_Bitcoin_Setup.md\",\n{\n 'v': 248,\n 'f': \"248\",\n }],\n [\"03_1_Verifying_Your_Bitcoin_Setup.md\",\n{\n 'v': 773,\n 'f': \"773\",\n }],\n [\"03_2_Knowing_Your_Bitcoin_Setup.md\",\n{\n 'v': 517,\n 'f': \"517\",\n }],\n [\"03_3_Setting_Up_Your_Wallet.md\",\n{\n 'v': 1699,\n 'f': \"1699\",\n }],\n [\"03_3__Interlude_Using_Command-Line_Variables.md\",\n{\n 'v': 347,\n 'f': \"347\",\n }],\n [\"03_4_Receiving_a_Transaction.md\",\n{\n 'v': 1479,\n 'f': \"1479\",\n }],\n [\"03_5_Understanding_the_Descriptor.md\",\n{\n 'v': 1349,\n 'f': \"1349\",\n }],\n [\"04_0_Sending_Bitcoin_Transactions.md\",\n{\n 'v': 176,\n 'f': \"176\",\n }],\n [\"04_1_Sending_Coins_The_Easy_Way.md\",\n{\n 'v': 1195,\n 'f': \"1195\",\n }],\n [\"04_2_Creating_a_Raw_Transaction.md\",\n{\n 'v': 1720,\n 'f': \"1720\",\n }],\n [\"04_2__Interlude_Using_JQ.md\",\n{\n 'v': 1956,\n 'f': \"1956\",\n }],\n [\"04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md\",\n{\n 'v': 413,\n 'f': \"413\",\n }],\n [\"04_4_Sending_Coins_with_a_Raw_Transaction.md\",\n{\n 'v': 1024,\n 'f': \"1024\",\n }],\n [\"04_4__Interlude_Using_Curl.md\",\n{\n 'v': 1643,\n 'f': \"1643\",\n }],\n [\"04_5_Sending_Coins_with_Automated_Raw_Transactions.md\",\n{\n 'v': 614,\n 'f': \"614\",\n }],\n [\"04_6_Creating_a_Segwit_Transaction.md\",\n{\n 'v': 1172,\n 'f': \"1172\",\n }],\n [\"05_0_Controlling_Bitcoin_Transactions.md\",\n{\n 'v': 149,\n 'f': \"149\",\n }],\n [\"05_1_Watching_for_Stuck_Transactions.md\",\n{\n 'v': 595,\n 'f': \"595\",\n }],\n [\"05_2_Resending_a_Transaction_with_RBF.md\",\n{\n 'v': 1372,\n 'f': \"1372\",\n }],\n [\"05_3_Funding_a_Transaction_with_CPFP.md\",\n{\n 'v': 827,\n 'f': \"827\",\n }],\n [\"06_0_Expanding_Bitcoin_Transactions_Multisigs.md\",\n{\n 'v': 155,\n 'f': \"155\",\n }],\n [\"06_1_Sending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1764,\n 'f': \"1764\",\n }],\n [\"06_2_Spending_a_Transaction_to_a_Multisig.md\",\n{\n 'v': 1079,\n 'f': \"1079\",\n }],\n [\"06_3_Sending_an_Automated_Multisig.md\",\n{\n 'v': 613,\n 'f': \"613\",\n }],\n [\"07_0_Expanding_Bitcoin_Transactions_PSBTs.md\",\n{\n 'v': 169,\n 'f': \"169\",\n }],\n [\"07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md\",\n{\n 'v': 1393,\n 'f': \"1393\",\n }],\n [\"07_3_Integrating_with_Hardware_Wallets.md\",\n{\n 'v': 2150,\n 'f': \"2150\",\n }],\n [\"08_0_Expanding_Bitcoin_Transactions_Other.md\",\n{\n 'v': 139,\n 'f': \"139\",\n }],\n [\"08_1_Sending_a_Transaction_with_a_Locktime.md\",\n{\n 'v': 1483,\n 'f': \"1483\",\n }],\n [\"08_2_Sending_a_Transaction_with_Data.md\",\n{\n 'v': 580,\n 'f': \"580\",\n }],\n [\"09_0_Introducing_Bitcoin_Scripts.md\",\n{\n 'v': 196,\n 'f': \"196\",\n }],\n [\"09_1_Understanding_the_Foundation_of_Transactions.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"09_2_Running_a_Bitcoin_Script.md\",\n{\n 'v': 863,\n 'f': \"863\",\n }],\n [\"09_3_Testing_a_Bitcoin_Script.md\",\n{\n 'v': 1000,\n 'f': \"1000\",\n }],\n [\"09_4_Scripting_a_P2PKH.md\",\n{\n 'v': 838,\n 'f': \"838\",\n }],\n [\"09_5_Scripting_a_P2WPKH.md\",\n{\n 'v': 845,\n 'f': \"845\",\n }],\n [\"10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md\",\n{\n 'v': 170,\n 'f': \"170\",\n }],\n [\"10_1_Understanding_the_Foundation_of_P2SH.md\",\n{\n 'v': 1164,\n 'f': \"1164\",\n }],\n [\"10_2_Building_the_Structure_of_P2SH.md\",\n{\n 'v': 1284,\n 'f': \"1284\",\n }],\n [\"10_3_Running_a_Bitcoin_Script_with_P2SH.md\",\n{\n 'v': 323,\n 'f': \"323\",\n }],\n [\"10_4_Scripting_a_Multisig.md\",\n{\n 'v': 1016,\n 'f': \"1016\",\n }],\n [\"10_5_Scripting_a_Segwit_Script.md\",\n{\n 'v': 750,\n 'f': \"750\",\n }],\n [\"10_6_Spending_a_P2SH_Transaction.md\",\n{\n 'v': 384,\n 'f': \"384\",\n }],\n [\"11_0_Empowering_Timelock_with_Bitcoin_Scripts.md\",\n{\n 'v': 108,\n 'f': \"108\",\n }],\n [\"11_1_Understanding_Timelock_Options.md\",\n{\n 'v': 557,\n 'f': \"557\",\n }],\n [\"11_2_Using_CLTV_in_Scripts.md\",\n{\n 'v': 1197,\n 'f': \"1197\",\n }],\n [\"11_3_Using_CSV_in_Scripts.md\",\n{\n 'v': 1470,\n 'f': \"1470\",\n }],\n [\"12_0_Expanding_Bitcoin_Scripts.md\",\n{\n 'v': 99,\n 'f': \"99\",\n }],\n [\"12_1_Using_Script_Conditionals.md\",\n{\n 'v': 1120,\n 'f': \"1120\",\n }],\n [\"12_2_Using_Other_Script_Commands.md\",\n{\n 'v': 407,\n 'f': \"407\",\n }],\n [\"13_0_Designing_Real_Bitcoin_Scripts.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"13_1_Writing_Puzzle_Scripts.md\",\n{\n 'v': 998,\n 'f': \"998\",\n }],\n [\"13_2_Writing_Complex_Multisig_Scripts.md\",\n{\n 'v': 996,\n 'f': \"996\",\n }],\n [\"13_3_Empowering_Bitcoin_with_Scripts.md\",\n{\n 'v': 1467,\n 'f': \"1467\",\n }],\n [\"14_0_Using_Tor.md\",\n{\n 'v': 116,\n 'f': \"116\",\n }],\n [\"14_1_Verifying_Your_Tor_Setup.md\",\n{\n 'v': 1568,\n 'f': \"1568\",\n }],\n [\"14_2_Changing_Your_Bitcoin_Hidden_Services.md\",\n{\n 'v': 434,\n 'f': \"434\",\n }],\n [\"14_3_Adding_SSH_Hidden_Services.md\",\n{\n 'v': 330,\n 'f': \"330\",\n }],\n [\"15_0_Talking_to_Bitcoind.md\",\n{\n 'v': 254,\n 'f': \"254\",\n }],\n [\"15_1_Accessing_Bitcoind_with_C.md\",\n{\n 'v': 1238,\n 'f': \"1238\",\n }],\n [\"15_2_Programming_Bitcoind_with_C.md\",\n{\n 'v': 1427,\n 'f': \"1427\",\n }],\n [\"15_3_Receiving_Bitcoind_Notifications_with_C.md\",\n{\n 'v': 650,\n 'f': \"650\",\n }],\n [\"16_0_Programming_with_Libwally.md\",\n{\n 'v': 333,\n 'f': \"333\",\n }],\n [\"16_1_Setting_Up_Libwally.md\",\n{\n 'v': 559,\n 'f': \"559\",\n }],\n [\"16_2_Using_BIP39_in_Libwally.md\",\n{\n 'v': 939,\n 'f': \"939\",\n }],\n [\"16_3_Using_BIP32_in_Libwally.md\",\n{\n 'v': 959,\n 'f': \"959\",\n }],\n [\"16_4_Using_PSBTs_in_Libwally.md\",\n{\n 'v': 989,\n 'f': \"989\",\n }],\n [\"16_5_Using_Scripts_in_Libwally.md\",\n{\n 'v': 785,\n 'f': \"785\",\n }],\n [\"16_6_Using_Other_Functions_in_Libwally.md\",\n{\n 'v': 655,\n 'f': \"655\",\n }],\n [\"16_7_Integrating_Libwally_and_Bitcoin-CLI.md\",\n{\n 'v': 1380,\n 'f': \"1380\",\n }],\n [\"17_0_Talking_to_Bitcoind_Other.md\",\n{\n 'v': 286,\n 'f': \"286\",\n }],\n [\"17_1_Accessing_Bitcoind_with_Go.md\",\n{\n 'v': 547,\n 'f': \"547\",\n }],\n [\"17_2_Accessing_Bitcoind_with_Java.md\",\n{\n 'v': 821,\n 'f': \"821\",\n }],\n [\"17_3_Accessing_Bitcoind_with_NodeJS.md\",\n{\n 'v': 393,\n 'f': \"393\",\n }],\n [\"17_4_Accessing_Bitcoind_with_Python.md\",\n{\n 'v': 1158,\n 'f': \"1158\",\n }],\n [\"17_5_Accessing_Bitcoind_with_Rust.md\",\n{\n 'v': 829,\n 'f': \"829\",\n }],\n [\"17_6_Accessing_Bitcoind_with_Swift.md\",\n{\n 'v': 1503,\n 'f': \"1503\",\n }],\n [\"18_0_Understanding_Your_Lightning_Setup.md\",\n{\n 'v': 192,\n 'f': \"192\",\n }],\n [\"18_1_Verifying_Your_Lightning_Setup.md\",\n{\n 'v': 1294,\n 'f': \"1294\",\n }],\n [\"18_2_Knowing_Your_lightning_Setup.md\",\n{\n 'v': 399,\n 'f': \"399\",\n }],\n [\"18_2__Interlude_Accessing_a_Second_Lightning_Node.md\",\n{\n 'v': 886,\n 'f': \"886\",\n }],\n [\"18_3_Setting_Up_a_Channel.md\",\n{\n 'v': 1173,\n 'f': \"1173\",\n }],\n [\"19_0_Using_Lightning.md\",\n{\n 'v': 146,\n 'f': \"146\",\n }],\n [\"19_1_Generate_a_Payment_Request.md\",\n{\n 'v': 968,\n 'f': \"968\",\n }],\n [\"19_2_Paying_a_Invoice.md\",\n{\n 'v': 604,\n 'f': \"604\",\n }],\n [\"19_3_Closing_a_Channel.md\",\n{\n 'v': 848,\n 'f': \"848\",\n }],\n [\"19_4_Lightning_Network_Review.md\",\n{\n 'v': 626,\n 'f': \"626\",\n }],\n [\"A0_Appendices.md\",\n{\n 'v': 112,\n 'f': \"112\",\n }],\n [\"A1_0_Understanding_Bitcoin_Standup.md\",\n{\n 'v': 420,\n 'f': \"420\",\n }],\n [\"A2_0_Compiling_Bitcoin_from_Source.md\",\n{\n 'v': 412,\n 'f': \"412\",\n }],\n [\"A3_0_Using_Bitcoin_Regtest.md\",\n{\n 'v': 980,\n 'f': \"980\",\n }],\n [\"CLA.md\",\n{\n 'v': 495,\n 'f': \"495\",\n }],\n [\"CONTRIBUTING.md\",\n{\n 'v': 529,\n 'f': \"529\",\n }],\n [\"LICENSE-CC-BY-4.0.md\",\n{\n 'v': 2716,\n 'f': \"2716\",\n }],\n [\"README.md\",\n{\n 'v': 1705,\n 'f': \"1705\",\n }],\n [\"TRANSLATING.md\",\n{\n 'v': 686,\n 'f': \"686\",\n }],\n [\"TOTAL\",\n{\n 'v': 89069,\n 'f': \"89069\",\n }]],\n columns: [[\"string\", \"Chapter\"], [\"number\", \"Word Count\"]],\n columnOptions: [],\n rowsPerPage: 25,\n helpUrl: \"https://colab.research.google.com/notebooks/data_table.ipynb\",\n suppressOutputScrolling: true,\n minimumWidth: undefined,\n });\n ", "text/plain": [ "" ], @@ -257,11 +269,6 @@ " ...\n", " \n", " \n", - " 5\n", - " CLA.md\n", - " 495\n", - " \n", - " \n", " 0\n", " CONTRIBUTING.md\n", " 529\n", @@ -281,16 +288,21 @@ " TRANSLATING.md\n", " 686\n", " \n", + " \n", + " 102\n", + " TOTAL\n", + " 89069\n", + " \n", " \n", "\n", - "

102 rows × 2 columns

\n", + "

103 rows × 2 columns

\n", "" ] }, "metadata": { "tags": [] }, - "execution_count": 5 + "execution_count": 6 } ] }, @@ -300,7 +312,7 @@ "id": "14kdusmNzcfz" }, "source": [ - "To convert the table to a markdown format and save as 'Chapter_word_counts.md'" + "Converts the table to a markdown format and save as 'Chapter_word_counts.md'" ] }, { @@ -327,7 +339,7 @@ " return '\\n'.join(['| {}'.format(row.split('|', 2)[-1]) for row in blob.split('\\n')])\n", " return blob" ], - "execution_count": 6, + "execution_count": 7, "outputs": [] }, { @@ -341,7 +353,7 @@ "with open('Chapter_word_counts.md', 'w') as m:\n", " m.write(str(mkdt.data))" ], - "execution_count": 7, + "execution_count": 8, "outputs": [] }, { @@ -350,14 +362,13 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "id": "_gGsbGDckIrC", - "outputId": "8d4bbec6-aa6e-465b-fec7-4251f7f4cecf" + "id": "kRKJUNcj_Fxl", + "outputId": "d826e833-2f4a-4f8f-b78f-cd07712c0f28" }, "source": [ - "total_count_translatable = chapter_word_counts['Word Count'].sum()\n", "total_count_translatable" ], - "execution_count": 8, + "execution_count": 9, "outputs": [ { "output_type": "execute_result", @@ -369,7 +380,7 @@ "metadata": { "tags": [] }, - "execution_count": 8 + "execution_count": 9 } ] } From cbf889f4cb5081c289703b369d6cbe80b8a4e344 Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Wed, 16 Jun 2021 23:05:17 -0500 Subject: [PATCH 14/50] typo in translatable --- Chapter_word_counts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Chapter_word_counts.md b/Chapter_word_counts.md index 4945dd2..406c1ee 100644 --- a/Chapter_word_counts.md +++ b/Chapter_word_counts.md @@ -1,6 +1,6 @@ ## Translatable word counts by chapter -Ignores code blocks and other non-translateable characters +Ignores code blocks and other non-translatable characters Chapter|Word Count ---|--- From 0fad79c78bc89b3c3e83f2ee2a117342cc27e830 Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Sat, 19 Jun 2021 18:21:23 -0500 Subject: [PATCH 15/50] missing space --- 05_2_Resending_a_Transaction_with_RBF.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/05_2_Resending_a_Transaction_with_RBF.md b/05_2_Resending_a_Transaction_with_RBF.md index 83ad3b9..4c9b9ae 100644 --- a/05_2_Resending_a_Transaction_with_RBF.md +++ b/05_2_Resending_a_Transaction_with_RBF.md @@ -2,7 +2,7 @@ If your Bitcoin transaction is stuck, and you're the sender, you can resend it using RBF (replace-by-fee). However, that's not all that RBF can do: it's generally a powerful and multipurpose feature that allows Bitcoin senders to recreate transactions for a variety of reasons. -> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.12.0,that reached full maturity in the Bitcoin Core wallet with Bitcoin Core v 0.14.0. Obviously, most people should be using it by now. +> :warning: **VERSION WARNING:** This is an innovation from Bitcoin Core v 0.12.0, that reached full maturity in the Bitcoin Core wallet with Bitcoin Core v 0.14.0. Obviously, most people should be using it by now. ## Opt-In for RBF From cb074778f807900bf8b2b84c1e08958f6bc764b0 Mon Sep 17 00:00:00 2001 From: Ian Culp <57159226+icculp@users.noreply.github.com> Date: Sat, 19 Jun 2021 18:23:03 -0500 Subject: [PATCH 16/50] removing ellipses --- 17_2_Accessing_Bitcoind_with_Java.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17_2_Accessing_Bitcoind_with_Java.md b/17_2_Accessing_Bitcoind_with_Java.md index ab85b40..26dbe1e 100644 --- a/17_2_Accessing_Bitcoind_with_Java.md +++ b/17_2_Accessing_Bitcoind_with_Java.md @@ -273,7 +273,7 @@ You now can sign transaction with the method `signRawTransactionWithKey`. This m Finally, sending requires the `sendRawTransaction` command: ```java String sentRawTransactionID = rpcClient.sendRawTransaction(srTx.hex()); -System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID);``` +System.out.println("Sent signedRawTx (txID): " + sentRawTransactionID); ``` ### Run Your Code From 07a1e4bab60c29c0f3f70d9c8f4d1d1f73610fb6 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 22 Jun 2021 08:23:12 -1000 Subject: [PATCH 17/50] added suggestion for a fork for each chapter. --- TRANSLATING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TRANSLATING.md b/TRANSLATING.md index 2d3c16b..fbcb755 100644 --- a/TRANSLATING.md +++ b/TRANSLATING.md @@ -15,9 +15,11 @@ Thank you for your interest in translating Learning Bitcoin from the Command Lin * We will create a top-level directory for your complete translation using the [ISO 639-1 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), for example `es` (Spanish), `fr` (French), or `pt` (Portuguese). Work should be done in that directory. 1. **Fork the Branch.** * Once we've created a translation branch, you'll then want to fork that into your own GitHub account. + * Generally, we suggest that you create one working fork for each separate chapter. This will allow you to work through the process of write/review/revise for each individual chapter without it getting tangled up with your new content for future chapters, and will allow us to merge the chapters as they're completed, which is our preference, and will help everyone to keep track of where things our. 1. **Submit PRs a Chapter at a Time.** * Submit your PRs for the translation from your working fork to our translation branch in batches of no more than a single chapter at a time. * Submit in smaller batches if it makes sense, for example because different people are writing different sections. + * Again, we suggest that there be a fork for each chapter, so when you submit your PR for one chapter, you'll usually then create a fork for the next chapter. 1. **Request Approval from a Native Speaker.** * No one can ever do a great edit of their own work, so we require each section to be approved by someone other than the original translator. * This fundamentally means that any translation team _should_ contain at least two members, either one translator and one editor or else two people who trade off roles of translator and editor. If your team doesn't have a second member, we can put out a call for an editor/approver when you submit a PR, but it's possible that we won't be able to find one, and your hard work will languish, so it's s better to have one up front. @@ -25,7 +27,7 @@ Thank you for your interest in translating Learning Bitcoin from the Command Lin * Once a chapter or section has been approved by a native speaker, request approval from someone on the Blockchain Commons team: currently [@shannona](https://github.com/shannona). 1. **Continue!** * Continue through the process, no more than one chapter at a time, until you have a full book. - * Be aware of the scope of the overall project. As of v2.01, Learning Bitcoin from the Command Line is 120,000 words in length. As a book, that'd be 250-400 pages, depending on the format and layout. (About 80,000 words of that is text to translate, with the remainder being code.) You want to make sure you have the time for that level of commitment before getting started. + * Be aware of the scope of the overall project. As of v2.01, Learning Bitcoin from the Command Line is 120,000 words in length. As a book, that'd be 250-400 pages, depending on the format and layout. (About 90,000 words of that is text to translate, with the remainder being code.) You want to make sure you have the time for that level of commitment before getting started. 1. **Let Us Know When You're Done.** * When you've completed your translation, file an issue to let us know that the translation branch is ready to be merged into the master. * This will also let us know to announce the completed translation and link it into the master README From d93085157bc244323306051da746673ad869b099 Mon Sep 17 00:00:00 2001 From: Shannon Appelcline Date: Tue, 22 Jun 2021 09:32:50 -1000 Subject: [PATCH 18/50] added translation links --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 9ee8172..7afe398 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,13 @@ Learning Bitcoin from the Command Line is a tutorial for working with Bitcoin (a _This tutorial assumes that you have some minimal background of how to use the command line interface. If not, there are many tutorials available, and I have one for Mac users at https://github.com/ChristopherA/intro-mac-command-line._ +## Translations + +* [Portuguese](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/portuguese-translation/pt) — in process +* [Spanish](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/spanish-translation/es) - in process + +If you'd like to make your own translation, please see [Contributing](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master#contributing), below. + ## Table of Contents ### PART ONE: PREPARING FOR BITCOIN From 9c675f05b6100b21a81b55a8e6db281d49f5fccf Mon Sep 17 00:00:00 2001 From: Javier Vargas Date: Wed, 23 Jun 2021 17:38:09 +0200 Subject: [PATCH 19/50] Fix Link 8.2 to 10.2 08_2_Building_the_Structure_of_P2SH.md 404 error --- 09_2_Running_a_Bitcoin_Script.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/09_2_Running_a_Bitcoin_Script.md b/09_2_Running_a_Bitcoin_Script.md index 67b3098..85cd0fd 100644 --- a/09_2_Running_a_Bitcoin_Script.md +++ b/09_2_Running_a_Bitcoin_Script.md @@ -12,7 +12,7 @@ Bitcoin Scripts are run from left to right. That sounds easy enough, because it' For example, if you were adding together "1" and "2", your Bitcoin Script for that would be `1 2 OP_ADD`, _not_ "1 + 2". Since we know that OP_ADD operator takes two inputs, we know that the two inputs before it are its operands. -> :warning: **WARNING:** Technically, everything in Bitcoin Script is an opcode, thus it would be most appropriate to record the above example as `OP_1 OP_2 OP_ADD`. In our examples, we don't worry about how the constants will be evaluated, as that's a topic of translation, as is explained in [§8.2: Building the Structure of P2SH](08_2_Building_the_Structure_of_P2SH.md). Some writers prefer to also leave the "OP" prefix off all operators, but we have opted not to. +> :warning: **WARNING:** Technically, everything in Bitcoin Script is an opcode, thus it would be most appropriate to record the above example as `OP_1 OP_2 OP_ADD`. In our examples, we don't worry about how the constants will be evaluated, as that's a topic of translation, as is explained in [§8.2: Building the Structure of P2SH](10_2_Building_the_Structure_of_P2SH.md). Some writers prefer to also leave the "OP" prefix off all operators, but we have opted not to. ### Understand the Stack From f26f691a2de3052d4c2f63c7a27a6ca27e21613a Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 23 Jun 2021 15:57:00 -0300 Subject: [PATCH 20/50] Sign Contributors Agreement --- ...A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 signed-cla/CLA.namcios.55A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc diff --git a/signed-cla/CLA.namcios.55A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc b/signed-cla/CLA.namcios.55A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc new file mode 100644 index 0000000..f6f773b --- /dev/null +++ b/signed-cla/CLA.namcios.55A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc @@ -0,0 +1,69 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +# Contributor License Agreement + +Version 1.0 + +Name: Namcios + +E-Mail: Namcios + +Legal Jurisdiction: Wyoming, United States of America + +Project: https://github.com/BlockchainCommons/bc-lethe-kit + +Date: 06/23/2021 + +## Purpose + +This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time. + +## License + +I hereby license Blockchain Commons, LLC to: + +1. do anything with my contributions that would otherwise infringe my copyright in them + +2. do anything with my contributions that would otherwise infringe patents that I can or become able to license + +3. sublicense these rights to others on any terms they like + +## Reliability + +I understand that Blockchain Commons will rely on this license. I may not revoke this license. + +## Awareness + +I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it. + +## Copyright Guarantee + +I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately. + +## Patent Guarantee + +I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms. + +## Open Source Guarantee + +I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms. + +## Disclaimers + +***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.*** + +- --- + +To sign this Contributor License Agreement, fill in `$name`, `$email`, and `$date` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./signed-cla/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com). +-----BEGIN PGP SIGNATURE----- + +iQEzBAEBCAAdFiEEVaJL4K7l20FSxqQQjjo2gxcmmrQFAmDTgZ4ACgkQjjo2gxcm +mrRTpQgAoFpCTvov11jIeyu4kNTbFy/lxdx5vXViWSvsPa2I/Q8TgTgWoAcBw84H +lqCDweT9dFFf3XXh2NTpgpAZ+TYbzBQgC3lNMc9BhKfgUOHnR+UFwAj7HyD2fPiE +e92BCLEmuSxk4ls8KFZ0wLySXNZGSehOb/K0EdYbw1szPQGEVmOvZq+vTkPfEDqO +XK3T81r5+YCwazQHNXbOwnpbVryqi700ndF8R7MTZ6Z1LqOKQCfXBLSBiDhQ8Wk6 +BhYbpXpJFGzlSrlfBG1jvQdUq2grAQ8CEhMprNJXPt294a6RAHMZ4bNz65OiAM4e +d/AaQ/DlwNvVZM7ARxorsucuqYkQUA== +=sF7Q +-----END PGP SIGNATURE----- From 5b467c817f89630085a5678fb74bc81c9021e9e3 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 23 Jun 2021 16:01:22 -0300 Subject: [PATCH 21/50] Fix email in Contributors Agreement --- .../CLA.namcios.55A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signed-cla/CLA.namcios.55A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc b/signed-cla/CLA.namcios.55A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc index f6f773b..eec8a6c 100644 --- a/signed-cla/CLA.namcios.55A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc +++ b/signed-cla/CLA.namcios.55A24BE0AEE5DB4152C6A4108E3A368317269AB4.asc @@ -7,7 +7,7 @@ Version 1.0 Name: Namcios -E-Mail: Namcios +E-Mail: namcios@protonmail.com Legal Jurisdiction: Wyoming, United States of America From f0bedd25c16105355f07681ecc3ffd41c3a47839 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 24 Jun 2021 21:30:52 -0300 Subject: [PATCH 22/50] Contributor License Agreement Signed --- ...BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 signed-cla/CLA.KoreaComK.F2BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc diff --git a/signed-cla/CLA.KoreaComK.F2BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc b/signed-cla/CLA.KoreaComK.F2BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc new file mode 100644 index 0000000..b342600 --- /dev/null +++ b/signed-cla/CLA.KoreaComK.F2BD6AD8C042ED6E9C5A232F3B909765FBEA7B30.asc @@ -0,0 +1,75 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + + +# Contributor License Agreement + +Version 1.0 + +Name: `KoreaComK` + +E-Mail: `koreacomk@protonmail.com` + +Legal Jurisdiction: Wyoming, United States of America + +Project: https://github.com/BlockchainCommons/bc-lethe-kit + +Date: `2021-06-16` + +## Purpose + +This agreement gives Blockchain Commons, LLC the permission it needs in order to accept my contributions into its open software project and to manage the intellectual property in that project over time. + +## License + +I hereby license Blockchain Commons, LLC to: + +1. do anything with my contributions that would otherwise infringe my copyright in them + +2. do anything with my contributions that would otherwise infringe patents that I can or become able to license + +3. sublicense these rights to others on any terms they like + +## Reliability + +I understand that Blockchain Commons will rely on this license. I may not revoke this license. + +## Awareness + +I promise that I am familiar with legal rules, like ["work made for hire" rules](http://worksmadeforhire.com), that can give employers and clients ownership of intellectual property in work that I do. I am also aware that legal agreements I might sign, like confidential information and invention assignment agreements, will usually give ownership of intellectual property in my work to employers, clients, and companies that I found. If someone else owns intellectual property in my work, I need their permission to license it. + +## Copyright Guarantee + +I promise not to offer contributions to the project that contain copyrighted work that I do not have legally binding permission to contribute under these terms. When I offer a contribution with permission, I promise to document in the contribution who owns copyright in what work, and how they gave permission to contribute it. If I later become aware that one of my contributions may have copyrighted work of others that I did not have permission to contribute, I will notify Blockchain Commons, in confidence, immediately. + +## Patent Guarantee + +I promise not to offer contributions to the project that I know infringe patents of others that I do not have permission to contribute under these terms. + +## Open Source Guarantee + +I promise not to offer contributions that contain or depend on the work of others, unless that work is available under a license that [Blue Oak Council rates bronze or better](https://blueoakconcil.org/list), such as the MIT License, two- or three-clause BSD License, the Apache License Version 2.0, or the Blue Oak Model License 1.0.0. When I offer a contribution containing or depending on others' work, I promise to document in the contribution who licenses that work, along with copies of their license terms. + +## Disclaimers + +***As far as the law allows, my contributions come as is, without any warranty or condition. Other than under [Copyright Guarantee](#copyright-guarantee), [Patent Guarantee](#patent-guarantee), or [Open Source Guarantee](#open-source-guarantee), I will not be liable to anyone for any damages related to my contributions or this contributor license agreement, under any kind of legal claim.*** + +- --- + +To sign this Contributor License Agreement, fill in `KoreaComK`, `koreacomk@protonmail.com`, and `2021-06-16` above. Then sign using GPG using the following command `gpg --armor --clearsign --output ./signed-cla/CLA.YOURGITHUBNAME.YOURGPGFINGERPRINT.asc CLA.md`, then either submit your signed Contributor License Agreement to this repo as a GPG signed Pull Request or email it to [ChristopherA@BlockchainCommons.com](mailto:ChristopherA@BlockchainCommons.com). +-----BEGIN PGP SIGNATURE----- + +iQIzBAEBCgAdFiEE8r1q2MBC7W6cWiMvO5CXZfvqezAFAmDKToEACgkQO5CXZfvq +ezCpJg/8DuIIHflWCcNSHljnOQgQfW/Qzys6axIB0FAO5E7VqZHD5tUzwThgxuU0 +BbniGNiqascqcMkTRWfOOXyx/Nef5bTt2CUqRU6k/3sK1VlXnWGB/zSikYeDWCUT +rggzQ052cBm103yiaOMg2Hx0Y4qTtcN/vJyXg0aESUXz+drMItKEaQBsF2fkwtPr +pGv7hqyu2O/u+9pMtZg8+lvHEPBdGfOVaCynrNLFTUE4+NSRNriPG/l5CTG8oEAC +h+e7HcZDiDVK2uQvhrPJLYhXWjiUqJ0MYpI9EKA88wkotUtilNsGKC8NqU724xIu +80hG+BeN9JWAR0wGPweVBtjkj1+hWNRbrm7ESK3gw53mfQBnAbpf23Rvk+tv24kG +/is8dAiHGHpLxBlD4DfGeyeKReXGjWhzaOkzJSBqXC0UBq3nyqcRQtbLd2hn0zpF +zm8/PwmB+PRGQ8TeRUa2j1o5ZUYyRCKtTARB68CrF0D26dpmtSheCGAqwp5mQqN2 +SBIHnFnFUTFJ3CEZJ4LVVGsHwfBt9BZL5D67grVJ9h19PLZsq9t4iEZLX47p8gP0 +Cp8YorqkelFZ/u+7VP1bJiZlX5E0Q/aGdLKemtSA5vbo4ua59fSw1bNWO9x19yt+ +u6u/PT8G5OoUhLldj4L8G3BFBXllb29nphtAVjh/PWxJj0dcupA= +=o+hW +-----END PGP SIGNATURE----- From 8be593a08fb2f6aedd9b83754917084614200cc8 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 24 Jun 2021 21:34:18 -0300 Subject: [PATCH 23/50] Chapter 01 translated The both files were revised by @lukedevj in the closed PR (https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/pull/224) --- pt/01_0_Introduction.md | 64 ++++++++++++++ pt/01_1_Introducing_Bitcoin.md | 150 +++++++++++++++++++++++++++++++++ 2 files changed, 214 insertions(+) create mode 100644 pt/01_0_Introduction.md create mode 100644 pt/01_1_Introducing_Bitcoin.md diff --git a/pt/01_0_Introduction.md b/pt/01_0_Introduction.md new file mode 100644 index 0000000..116b7e4 --- /dev/null +++ b/pt/01_0_Introduction.md @@ -0,0 +1,64 @@ + +# CAPÍTULO 1: Introdução à Aprendizagem do Bitcoin Core (& Lightning Network) pela linha de comando + +## Introdução + +Os modos como fazemos pagamentos por bens e serviços têm mudado drasticamente nas últimas décadas. Antigamente todas as transações eram realizadas utilizando dinheiro ou cheques, e atualmente os diversos métodos de pagamento eletrônico são à regra. Porém, a maioria dos pagamentos eletrônicos ainda ocorre utilizando sistemas centralizados, onde empresas de cartão de crédito, bancos ou até instituições financeiras baseadas apenas na Internet, como o PayPal, mantêm listas de transações longas e correlacionadas individualmente, tendo o poder de censurar as transações que não gostarem. + +Esses riscos de centralização foram alguns dos catalisadores primordiais para a criação de criptomoedas, sendo a primeira e mais bem sucedida, o Bitcoin. O Bitcoin oferece pseudonímia; torna difícil correlacionar as transações; e torna a censura por entidades individuais, algo próximo do impossível. Essas vantagens fizeram dele uma das moedas mais rápidas do mundo. Esse crescimento, por sua vez, despertou o interesse dos empresários e desenvolvedores, ansiosos para criar novos serviços para a comunidade do Bitcoin. + +Se você é um desses empreendedores ou desenvolvedores, então este curso é para você, porque ele tem tudo o que necessita para aprender a programar no Bitcoin. É um curso introdutório que explica todas as nuances e características do Bitcoin e de tudo o que vem com ele. O curso também oferece algumas coisas mais específicas, como aulas de como utilizar _diretamente_ o Bitcoin Core com o servidor C-Lightning usando suas interfaces RPC. + +Por que não utilizar algumas das bibliotecas mais detalhadas encontradas em várias linguagens de programação? Por que não criar a sua própria do zero? Porque trabalhar com criptomoedas é perigoso. Não há redes de segurança. Se você acidentalmente pagar taxas muito altas ou perder uma chave de assinatura ou criar uma transação inválida ou fazer qualquer outros milhares de erros potenciais, você dará adeus a suas moedas para sempre. Muito dessa responsabilidade, é claro, fica com você como sendo um programador de criptomoedas, mas também pode ser minimizado, trabalhando com as interfaces de criptomoedas mais robustas e seguras que estão disponíveis, as que foram criadas pelas próprias equipes de programação dessas criptomoedas: A ``Bitcoind`` e a ``Lightningd``. + +Grande parte deste livro discute como fazer um script em bitcoin (e na Lightning Network) diretamente pela linha de comando. Alguns capítulos adiantes lidam com linguagens de programação mais sofisticadas, mas novamente continuam a interagir diretamente com o `` Bitcoind`` e a ``Lightningd``, usando o RPC ou interagindo com os arquivos que são criados por eles. Isso permite que você se mantenha no mesmo nível dos gigantes e use a tecnologia confiável para aprender como criar seus próprios sistemas confiáveis. + +## Nível de Habilidade Necessária + +Você não precisa ser particularmente uma pessoa da área técnica para boa parte deste curso. Tudo o que precisará é a confiança para executar comandos básicos pela linha de comando do UNIX. Se você está familiarizado com coisas como ``ssh``, ``cd``, e ``ls``, o curso irá te fornecer o resto. + +Uma minoria deste curso requer conhecimento de programação, e você deve pular essas seções, se necessário, conforme iremos discutir na próxima seção. + +## Resumo dos tópicos + +Este livro é dividido nas seguintes seções: + +| Parte | Descrição | Habilidades | +|-------|---------|---------| +| **Parte 1: Se preparando para o Bitcoin** | Entendendo os fundamentos do Bitcoin e configurando um servidor para uso. | Linha de Comando | +| **Parte 2: Usando o bitcoin-cli** | Usando o Bitcoin-cli para criar transações. | Linha de Comando | +| **Parte 3: Fazendo scripts com Bitcoin** | Expandindo seu trabalho no bitcoin com scripts. | Conceitos de Programação | +| **Parte 4: Usando o Tor** | Melhorando a segurança do _node_ com tor | Linha de Comando | +| **Parte 5: Programando com RPC** | Acessando o RPC com C e outras linguagens. | Programando em C | +| **Parte 6: Usando a lightning-cli** | Usando a Lightning-CLI para criar transações. | Linha de Comando | +| **Apêndices.** | Utilizando configurações incomuns no Bitcoin. | Linha de Comando | + +## Como Usar Este Curso + +Então, por onde você começa? Este livro é destinado principalmente para ser lido em sequência. Basta seguir o "O que vem depois?" que estarão no final de cada seção e/ou clicar nos links individuais de cada seção em cada página do capítulo. Você conseguirá o melhor entendimento deste curso se realmente se construir um servidor Bitcoin (no capítulo 2) e, em seguida, passar por todos os exemplos que estarão disponíveis ao longo do livro: Testar os exemplos é uma excelente metodologia de aprendizado. + +Se você tem diferentes níveis de habilidade ou se quiser aprender coisas diferentes, poderá pular para algumas partes diferentes do livro: + +* Se você já tem um ambiente pronto do Bitcoin para ser utilizado, vá para o [Capítulo 3: Entendendo sua configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md). +* Se você só se importa com os Scriptos em Bitcoin, pule para o [Capítulo 9: Apresentando os Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md). +* Se você quiser apenas ler sobre o uso das linguagens de programação, pule para o [Capítulo 15: Falando com o Bitcoin](15_0_Talking_to_Bitcoind.md). +* Se não quer programar nada, definitivamente ignore os capítulos 15 ao 17 enquanto estiver lendo, e talvez seja melhor pular os capítulos 9 ao 13. O resto do curso ainda deve fazer sentido sem eles. +* Se estiver interessado apenas na Lightning Network, corra para o [Capítulo 18: Entendendo sua configuração da Lightning Network](18_0_Understanding_Your_Lightning_Setup.md). +* Se quiser ler o conteúdo novo adicionado na versão 2 do curso (2020), seguido da versão 1 (2017), leia [§3.5: Entendendo o descritor](03_5_Understanding_the_Descriptor.md), [§4.6: Criando uma transação SegWit](04_6_Creating_a_Segwit_Transaction.md), [Capítulo 7: Expandindo o Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md), [§9.5: Criando um script P2WPKH](09_5_Scripting_a_P2WPKH.md), [§10.5: Criando um script SegWit](10_5_Scripting_a_Segwit_Script.md), [Capítulo 14: Usando o Tor](14_0_Using_Tor.md), [Capítulo 15: Conversando com o Bitcoin com C](15_0_Talking_to_Bitcoind.md), [Capítulo 16: Programando com Libwally](16_0_Programming_with_Libwally.md), [Capítulo 17: Conversando com o Bitcoind usando outras linguagens](17_0_Talking_to_Bitcoind_Other.md), [Capítulo 18: Entendendo sua configuração da Lightning ](18_0_Understanding_Your_Lightning_Setup.md), e [Capítulo 19: Usando a Lightning](19_0_Using_Lightning.md). + +## Por Que Utilizar Este Curso + +Obviamente, você está querendo fazer este curso porque está interessado no Bitcoin. Além de transmitir o conhecimento básico, também ajudará os leitores a participar (ou criar) projetos open source e obter empregos de cargos júnior na área de programação envolvendo o Bitcoin. Um número de estagiários na Blockchain Commons aprendeu sobre o Bitcoin através deste curso, e muitos dos membros da nossa equipe de programação também. + +## Como Ajudar Este Curso + +* Por favor, use a área de [Issues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/issues) para quaisquer dúvidas. A Blockchain Commons não tem uma equipe ativa de suporte, e não podemos abordar problemas ou perguntas individuais, mas olharemos iremos tratá-los com o tempo e os usaremos para melhorar nossas futuras iterações no curso. +* Por favor, use os [PRs](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/pulls) para quaisquer correções de erros de digitação ou comandos incorretos (ou que foram alterados). Para alterações técnicas ou de linha de comando, é muito útil se você usar também os comentários para explicar por que fez o que você fez, para que não precisemos gastar tempo pesquisando o motivo. +* Por favor, use nossa [Área de Discussão da Comunidade](https://github.com/BlockchainCommons/Community/discussions) para falar sobre carreiras e habilidades. A Blockchain Commons ocasionalmente oferece estágios, como falado em nosso repo da comunidade. +* Por favor, [torne-se um patrono](https://github.com/sponsors/BlockchainCommons) se achar este curso útil ou se quiser ajudar a educar a próxima geração de programadores da blockchain. + +## O Que Vem Depois? + +Se você quiser uma introdução básica ao Bitcoin, criptografia de chave pública, ECC, blockchains e Lightning Network, leia o prefácio [Introdução ao Bitcoin](01_1_Introducing_Bitcoin.md). + +Caso contrário, se já estiver pronto para mergulhar de cabeça no curso, vá para [Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md). diff --git a/pt/01_1_Introducing_Bitcoin.md b/pt/01_1_Introducing_Bitcoin.md new file mode 100644 index 0000000..5408df8 --- /dev/null +++ b/pt/01_1_Introducing_Bitcoin.md @@ -0,0 +1,150 @@ + +# Prefácio: Apresentando o Bitcoin + +Antes de começar a programar em Bitcoin (e Lightning), você deve ter uma compreensão básica do que são e como funcionam. Esta seção fornece essa visão geral. Várias outras definições irão aparecer mais à frente. O objetivo deste capítulo é apenas dar o conteúdo base. + +## Sobre o Bitcoin + +O Bitcoin é um sistema programável que permite a transferência da moeda bitcoin. Tem como base um sistema descentralizado _peer-to-peer_ (de ponta à ponta) de nodes, que inclui full nodes, carteiras e mineradores. Trabalhando juntos, eles garantem que as transações do bitcoin sejam rápidas e irreversíveis. Graças à natureza descentralizada do sistema, essas transações também são resistentes à censura e podem fornecer outras vantagens, como pseudo-anonimato, caso sejam bem utilizadas. + +Obviamente, Bitcoin é o coração deste livro, mas também é o originador de muitos outros sistemas, incluindo a blockchain e Lightning, que são detalhados neste tutorial, e muitas outras criptomoedas, como Ethereum e Litecoin, que não são. + +**_Como as moedas são transferidas?_** O Bitcoin não possui moedas físicas. Elas são uma série interminável de trocas títulos de propriedade. Quando uma pessoa envia as moedas para outra, essa transferência é armazenada como uma transação. É a transação que realmente registra a propriedade do dinheiro, isso significa que não existe nenhuma moeda que sai da carteira ou da máquina do proprietário. + +**_Para quem você pode enviar as moedas?_** A grande maioria das transações de bitcoin envolvem o envio de moedas para pessoas comuns (ou pelo menos para endereços Bitcoin de pessoas comuns). No entanto, metodologias mais complexas podem ser usadas para enviar bitcoins para um grupo de pessoas ou para scripts. Essas várias metodologias possuem nomes como P2PKH, multisig e P2SH. + +**_Como as transações são armazenadas?_** As transações são combinadas em grandes blocos de dados, que são gravados na _ledger da blockchain_. Um bloco é construído de tal forma que não pode ser substituído ou reescrito, uma vez que vários blocos tenham sido construídos depois dele. Isso é o que torna os bitcoins irreversíveis: Um livro razão (_ledger_) global descentralizado, onde tudo é registrado, é efetivamente um banco de dados permanente e imutável. + +Porém, o processo de construção desses blocos é estocástico: É um tanto aleatório, então não podemos ter certeza se uma transação será colocada em um bloco específico. Também pode haver alterações nos blocos se forem muito recentes, mas apenas se forem _muitíssimo_ recentes. Então, as coisas se tornam irreversíveis (permanentes, imutáveis) depois de um alguns minutos. + +**_Como as transações são protegidas?_** Os fundos contidos em uma transação Bitcoin são assegurados por um quebra-cabeça criptográfico. Esses quebra-cabeças são projetados para que possam ser facilmente resolvidos pela pessoa para quem os fundos foram enviados. Isso é feito usando o poder da criptografia de chave pública. Tecnicamente, uma transação é protegida por uma assinatura que prova que você é o proprietário da chave pública para a qual a transação foi enviada: Essa prova de propriedade é o quebra-cabeça que está sendo resolvido. + +Os fundos são protegidos pelo uso de hashes. As chaves públicas não são realmente armazenadas na blockchain até que os fundos sejam gastos: Apenas os hashes de chave pública são. Isso significa que, mesmo que um computador quântico seja criado, as transações do Bitcoin permaneceriam protegidas por esse segundo nível de criptografia. + +**_Como as transações são criadas?_** O coração de cada transação do Bitcoin é uma linguagem script do tipo FORTH usada para bloquear a transação. Para reenviar o dinheiro, o destinatário fornece informações específicas ao script que prova que ele é o destinatário pretendido. + +No entanto, esses scripts do Bitcoin são o nível mais baixo de funcionalidade deste protocolo. Grande parte do trabalho do Bitcoin é feito através do `bitcoind` do Bitcoin, que é controlado por meio de comandos RPC. Muitas pessoas enviam esses comandos RPC por meio do programa chamado `bitcoin-cli`, que fornece uma interface ainda mais simples. Os não programadores nem mesmo se preocupam com essas minúcias, permitindo o uso de carteiras programáveis com interfaces mais simples. + +### Resumindo o Bitcoin + +Uma maneira de pensar no Bitcoin é como _uma sequência de transações atômicas_. Cada transação é autenticada por um remetente com a solução para um quebra-cabeça criptográfico anterior que foi armazenado como um script. A nova transação é bloqueada para o destinatário com um novo quebra-cabeça criptográfico que também é armazenado como um script. Cada transação é registrada no livro razão global imutável. + +## Sobre criptografia de chave pública + +A criptografia de chave pública é um sistema matemático para proteção de dados e comprovação de propriedade por meio de um par assimétrico de chaves que estão vinculadas entre si: a chave pública e a chave privada. + +É importante para o Bitcoin (e para a maioria dos sistemas que utilizam a blockchain) porque é a base de grande parte da criptografia que protege os fundos das criptomoedas. Uma transação de Bitcoin é normalmente enviada para um endereço que é um hash da chave pública. O destinatário pode então recuperar o dinheiro utilizando a chave pública e a chave privada. + +**_O que é uma chave pública?_** Uma chave pública é a chave fornecida as demais pessoas. Em um sistema de chave pública comum, um usuário gera uma chave pública e uma chave privada e, em seguida, dá a chave pública para as pessoas. Esses destinatários podem criptografar informações com a chave pública, mas não podem ser descriptografadas com a mesma chave devido à assimetria do par de chaves. + +**_O que é uma chave privada?_** Uma chave privada está vinculada a uma chave pública em um par de chaves. Em um sistema de chave pública comum, um usuário mantém sua chave privada segura e a usa para descriptografar as mensagens que foram criptografadas com sua chave pública antes de serem enviadas a ele. + +**_O que é uma assinatura?_** Uma mensagem (ou mais comumente, um hash de uma mensagem) pode ser assinada com uma chave privada, criando uma assinatura. Qualquer pessoa com a chave pública correspondente pode validar a assinatura, o que verifica se o assinante possui a chave privada associada à chave pública em questão. O _SegWit_ é um formato específico para armazenar uma assinatura na rede Bitcoin que falaremos mais especificamente no futuro. + +**_O que é uma função hash?_** Uma função hash é um algoritmo frequentemente usado com a criptografia. É uma maneira de mapear uma grande quantidade arbitrária de dados em uma quantidade pequena e fixa de dados. As funções hash usadas na criptografia são unilaterais e resistentes a colisões, o que significa que um hash pode ser vinculado de forma confiável aos dados originais, mas os dados originais não podem ser regenerados a partir do hash. Assim, os hashes permitem a transmissão de pequenas quantidades de dados para representar grandes quantidades de dados, o que pode ser importante para a eficiência e os requisitos de armazenamento. + +O Bitcoin aproveita a capacidade do hash de disfarçar os dados originais, o que permite ocultar a chave pública real do usuário, tornando as transações resistentes à computação quântica. + +### Resumindo a criptografia de chave pública + +Uma maneira de pensar na criptografia de chave pública é: _um jeito de qualquer pessoa proteger os dados de forma que apenas uma pessoa autorizada possa acessá-los e também possa provar que tem esse acesso._ + +## Sobre CCE + +O CCE é um acrônimo para criptografia de curva elíptica. É um ramo específico da criptografia de chave pública que depende de cálculos matemáticos usando curvas elípticas definidas sobre campos finitos. É mais complexo e difícil de explicar do que a criptografia de chave pública clássica (que usava números primos), mas tem algumas vantagens interessantes. + +O CCE não terá tanta atenção neste tutorial. Isso porque falaremos mais sobre a integração com servidores Bitcoin Core e Lightning, que já cuidaram da parte criptografia para você. Na verdade, a intenção deste tutorial é que você não precise se preocupar com a criptografia, porque isso é algo que você _realmente_ deseja que os especialistas lidem. + +**_O que é uma curva elíptica?_** Uma curva elíptica é uma curva geométrica que assume a forma ``y`` `` 2`` = ``x`` ``3`` `` + ax + b``. Uma curva elíptica específica é escolhida selecionando valores específicos de ``a`` e ``b``. A curva deve ser examinada cuidadosamente para determinar se funciona bem para criptografia. Por exemplo, a curva secp256k1 usada pelo Bitcoin é definida como ``a = 0`` e ``b = 7``. + +Qualquer linha que cruze uma curva elíptica o fará em 1 ou 3 pontos... e essa é a base da criptografia de curva elíptica. + +**_O que são campos finitos?_** Um campo finito é um conjunto finito de números, onde todas as adições, subtrações, multiplicações e divisões são definidas de forma que resultem em outros números que também estarão no mesmo campo finito. Uma maneira simples de criar um campo finito é por meio do uso da aritmética modular. + +**_Como uma curva elíptica é definida sobre um campo finito?_** Uma curva elíptica definida sobre um campo finito tem todos os pontos em sua curva desenhados a partir de um campo finito específico. Ele assume a forma: ``y````2````% tamanho-do-campo = (x````3```` + ax + b) % tamanho-do-campo``. O campo finito usado para secp256k1 é ``2````256````-2````32````-2````9````-2````8````-2````7````-2````6````-2````4````-1``. + +**_Como as curvas elípticas são usadas na criptografia?_** Na criptografia de curva elíptica, um usuário seleciona um número muito grande (256 bits) como sua chave privada. Ele então adiciona um ponto base definido na curva a si mesmo tantas vezes. (Na secp256k1, o ponto de base é ``G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8`` que prefixa as duas partes da tupla com um ``04`` para dizer que o ponto de dados está na forma descompactada. Se você preferir uma definição geométrica direta, é o ponto "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD0817B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD0817B44810A"). O número resultante é uma chave pública. Várias fórmulas matemáticas podem então ser usadas para provar a propriedade da chave pública, dada a chave privada. Como acontece com qualquer função criptográfica, esta é uma armadilha: É fácil passar de uma chave privada para uma chave pública e praticamente impossível de passar de uma chave pública para uma chave privada. + +Essa metodologia específica também explica por que os campos finitos são usados ​​em curvas elípticas: Ela garante que a chave privada não ficará muito grande. Observe que o campo finito para secp256k1 é ligeiramente menor que 256 bits, o que significa que todas as chaves públicas terão 256 bits, assim como as chaves privadas. + +**_Quais são as vantagens do CCE?_** A principal vantagem do CCE é que ele permite a mesma segurança da criptografia de chave pública clássica com uma chave muito menor. Uma chave pública de curva elíptica de 256 bits corresponde a uma chave pública tradicional (RSA) de 3072 bits. + +### Resumindo o CCE + +Uma maneira de pensar no CCE é: _Um jeito de permitir a criptografia de chave pública usando chaves muito pequenas e uma matemática bem obscura._ + +## Sobre Blockchains + +A blockchain é a generalização da metodologia usada pelo Bitcoin para criar um livro razão distribuído globalmente. O Bitcoin é uma blockchain, assim como qualquer outra moeda alternativa, cada um dos quais vive em sua própria rede e grava em sua própria cadeia de blocos. As sidechains como a _Liquid_ são blockchains também. As blockchains não precisam necessariamente ser relacionadas com finanças. Por exemplo, existem várias discussões para implementar blockchains em soluções para proteger identidades autossoberanas. + +Embora precise entender os fundamentos de como uma blockchain funciona para entender como as transações funcionam no Bitcoin, não é necessário muito mais do que isso. Como as blockchains se tornaram uma ampla categoria de tecnologia, esses conceitos básicos provavelmente serão aplicáveis ​​a muitos outros projetos neste setor de tecnologia em crescimento. Porém, os comandos de programação específicos aprendidos neste livro não serão abrangentes a várias utilizações, já que são específicos para Bitcoin (e para a Lightning). + +**_Por que é chamado de cadeia de blocos?_** Cada bloco na blockchain armazena um hash do bloco anterior. Isso liga o bloco atual de volta ao "bloco de gênese" original por meio de uma cadeia de blocos ininterrupta. É uma forma de criar uma ordem absoluta entre os dados possivelmente conflitantes. Isso também fornece a segurança da blockchain, porque cada bloco é empilhado sobre um antigo tornando mais difícil recriar o bloco antigo devido aos algoritmos de prova de trabalho utilizados ​​na criação do bloco. Depois que vários blocos foram construídos sobre uma cadeia de blocos, ele é essencialmente irreversível. + +**_O que é um fork?_** Ocasionalmente, dois blocos são criados ao mesmo tempo. Isso cria, temporariamente, um fork de um bloco, onde qualquer um dos blocos atuais pode ser o "verdadeiro". De vez em quando, um fork pode se expandir para dois blocos, três blocos ou mesmo quatro blocos de comprimento, mas muito rapidamente um lado da bifurcação é determinado como o verdadeiro e o outro se torna o que chamamos de "órfão". Isso faz parte do processo estocástico de criação de bloco e demonstra por que vários blocos devem ser construídos sobre um bloco antes que ele possa ser considerado verdadeiramente confiável e não rejeitável. + +### Resumindo a blockchain + +Uma maneira de pensar na blockchain é: _Uma série vinculada de blocos de dados imutáveis, até o seu bloco inicial._ +Outra forma é: _Uma série de blocos vinculados para ordenar dados absolutos que podem ser conflitantes_. + +## A Blockchain é adequada para mim? + +Se você deseja negociar bitcoins, então obviamente a Bitcoin é adequada para você. No entanto, de forma mais ampla, a blockchain se tornou uma cultura pop da atualidade, embora não seja uma solução mágica para todos os problemas técnicos. Dito isso, existem muitas situações específicas em que a blockchain é uma tecnologia superior. + +Blockchains provavelmente _são_ úteis nos seguintes casos: + +* Os usuários não confiam uns nos outros. + * Ou: Os usuários estão em diferentes localidades. + * Os usuários não confiam nas autoridades centrais. + * E: Os usuários desejam controlar seus próprios destinos. + * Os usuários desejam uma tecnologia transparente. + * Os usuários desejam compartilhar algo. + * E: Os usuários desejam que o que é compartilhado seja registrado permanentemente. + * Os usuários desejam uma transação final rápida. + * Mas: Os usuários não precisam de uma transação final instantânea. + +Blockchains provavelmente _não_ serão úteis caso: + +* Os usuários sejam confiáveis: + * Por exemplo: As transações ocorrem dentro de uma empresa ou organização. + * Por exemplo: As transações são supervisionadas por uma autoridade central. + * O sigilo é obrigatório: + * Por exemplo: As informações devem ser secretas. + * Por exemplo: As transações devem ser secretas. + * Por exemplo: As pessoas que estão transacionando devem ser secretas. + * A menos que: uma metodologia para sigilo criptográfico seja cuidadosamente considerada, analisada e testada. + * Os usuários precisam de transações finais instantâneas: + * Por exemplo: Em menos de 10 minutos em uma rede semelhante a Bitcoin, em menos de 2,5 minutos em uma rede semelhante a Litecoin, em menos de 15 segundos em uma rede semelhante a Ethereum. + +Observe que ainda pode haver soluções para algumas dessas situações dentro do ecossistema Bitcoin. Por exemplo, os canais de pagamento estão lidando rapidamente com questões de liquidez e finalização do pagamento. + +## Sobre a Lightning (Network) + +A lightning é um protocolo de segunda camada que interage com o Bitcoin para permitir que os usuários troquem seus bitcoins "offchain" (fora da blockchain). Possui vantagens e desvantagens em relação ao uso da camada principal do Bitcoin. + +A lightning também é um dos focos deste tutorial. Embora o ponto principal seja sobre a interação direta com o Bitcoin (e o `bitcoind`), vamos falar um pouco sobre a lightning e o porque é uma tecnologia que está prestes a se tornar uma alternativa popular ao Bitcoin, em um futuro próximo. Este livro tem a mesma abordagem para a lightning e para o Bitcoin: Ele ensina como interagir diretamente com a Lightning de maneira confiável à partir da linha de comando. + +Ao contrário do Bitcoin, existem várias variantes da lightning. Este tutorial usa a implementação compatível do padrão [C-lightning](https://github.com/ElementsProject/lightning) como sendo seu servidor lightning confiável. + +**_O que é um protocolo de segunda camada?_** Um protocolo de segunda camada no Bitcoin funciona tendo como base o Bitcoin. Nesse caso, a lightning trabalha em cima do Bitcoin, interagindo com ele por meio de contratos inteligentes. + +**_O que é um canal lightning?_** Um canal Lightning é uma conexão entre dois usuários utilizando a lightning. Cada um dos usuários bloqueia uma quantidade de bitcoins na blockchain do Bitcoin usando uma assinatura multi-sig, criada e assinada por ambos. Os dois usuários podem, então, trocar bitcoins por meio do canal lightning sem precisar gravar nada na blockchain Bitcoin. Somente quando desejam fechar o canal, eles liquidam os bitcoins, com base na divisão no saldo final das partes. + +**_O que é a Lightning Network?_** A junção de todos os canais da lightning criam a Lightning Network. Isso permite que dois usuários que não tenham um canal entre si troquem bitcoins usando Lightning: O protocolo forma uma cadeia de canais entre os dois usuários e, em seguida, troca as moedas através da cadeia usando transações que chamamos de _time-locked transactions_. + +**_Quais são as vantagens da lightning?_** A lightning permite transações mais rápidas com taxas mais baixas. Isso cria a possibilidade real de micropagamentos usando bitcoin. Ela também oferece maior privacidade, uma vez que está fora da rede, com apenas o primeiro e o último estado da transação sendo gravados blockchain do Bitcoin. + +**_Quais são as desvantagens do Lightning?_** A lightning ainda é uma tecnologia muito nova e não foi testada tão exaustivamente quanto o Bitcoin. Isso não é apenas uma questão de implementação tecnológica, mas também se o design que pode ser manipulado de maneiras não pensadas anteriormente. + +### Resumindo a lightning + +Uma maneira de pensar na Lightning é: _Um jeito de transacionar bitcoins usando canais offchain entre duas pessoas, de modo que apenas o primeiro e o último estado precisem ser gravados na blockchain_. + +## Resumo: Apresentando o Bitcoin + +O Bitcoin é um sistema _peer-to-peer_ que permite a transferência de fundos por meio de transações bloqueadas por quebra-cabeças. Esses quebra-cabeças dependem da criptografia de curva elíptica de chave pública. Quando você generaliza as ideias por trás do Bitcoin, encontra-se as blockchains, uma tecnologia que atualmente está crescendo e inovando muitos setores. Quando você expande as ideias por trás do Bitcoin, obtém protocolos de segunda camada, como a lightning, que expandem o potencial da moeda. + +## O Que Vem Depois? + +Vamos avançar para "se preparar para o Bitcoin" com o [Capítulo Dois: Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md). \ No newline at end of file From 2c321c21e95ee5c114caaef0f2e16ace5da1e2b1 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 24 Jun 2021 21:42:10 -0300 Subject: [PATCH 24/50] Chapter 02 translated The file was revised by @lukedevj in the closed PR (#224) --- pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md diff --git a/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md b/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md new file mode 100644 index 0000000..5f5ae45 --- /dev/null +++ b/pt/02_0_Setting_Up_a_Bitcoin-Core_VPS.md @@ -0,0 +1,27 @@ + +# Capítulo 2: Configurando um Bitcoin-Core no VPS + +Para começar a usar o Bitcoin, primeiro precisamos configurar uma máquina que execute o Bitcoin. Os artigos neste capítulo descrevem como fazer isso, principalmente usando um VPS (Virtual Private Server). + +## Objetivos deste Capítulo + +Depois de passar por este capítulo, um desenvolvedor será capaz de: + +* Decidir entre os cinco principais tipos de nodes de Bitcoin; +* Criar um node Bitcoin para desenvolvimento; +* Crie uma instância local da Blockchain do Bitcoin. + +Os objetivos secundários incluem a capacidade de: + + * Compreender a configuração da rede básica do VPS; + * Decidir quais prioridades de segurança implementar; + * Entender a diferença entre os nodes prunados e os não prunados; + * Entender a diferença entre nodes Mainnet, Testnet e Regtest; + * Interpretar os fundamentos do arquivo de configuração do Bitcoin. + +## Tabela de Conteúdo + +Na verdade, não é preciso ler este capítulo inteiro. Decida se gostaria de executar um StackScript para configurar um node em um VPS Linode (§2.2); Ou você deseja configurar em um ambiente diferente, como em uma máquina AWS ou um Mac (§2.3). Em seguida, vá para a seção mais apropriada. Informações adicionais sobre nossas configurações sugeridas também podem ser encontradas no [Apêndice I](A1_0_Understanding_Bitcoin_Standup.md). + + * [Seção Um: Configurando um Bitcoin Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) + * [Seção Dois: Configurando uma máquina Bitcoin Core usando outros meios](02_2_Setting_Up_Bitcoin_Core_Other.md) \ No newline at end of file From 3d9d4eec1958a62cfa5f302df84cd0b6b5cc9b70 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Thu, 24 Jun 2021 21:44:30 -0300 Subject: [PATCH 25/50] Chapter 15 Translated The four files were revised by @lukedevj in the closed PR (#224) --- pt/15_0_Talking_to_Bitcoind.md | 27 ++ pt/15_1_Accessing_Bitcoind_with_C.md | 294 +++++++++++++++ pt/15_2_Programming_Bitcoind_with_C.md | 354 ++++++++++++++++++ ...Receiving_Bitcoind_Notifications_with_C.md | 155 ++++++++ 4 files changed, 830 insertions(+) create mode 100644 pt/15_0_Talking_to_Bitcoind.md create mode 100644 pt/15_1_Accessing_Bitcoind_with_C.md create mode 100644 pt/15_2_Programming_Bitcoind_with_C.md create mode 100644 pt/15_3_Receiving_Bitcoind_Notifications_with_C.md diff --git a/pt/15_0_Talking_to_Bitcoind.md b/pt/15_0_Talking_to_Bitcoind.md new file mode 100644 index 0000000..88bde29 --- /dev/null +++ b/pt/15_0_Talking_to_Bitcoind.md @@ -0,0 +1,27 @@ + +# Capítulo 15: Conversando com Bitcoind usando C + +Enquanto trabalhamos com Bitcoin Scripts, atingimos os limites do que era possível com o `bitcoin-cli`: Atualmente, ele não pode ser usado para gerar transações contendo scripts incomuns. Os scripts shell também não são bons para algumas coisas, como criar programas de escuta que estão constantemente em polling. Felizmente, existem outras maneiras de acessar a rede Bitcoin: Através de APIs programáveis. + +Esta seção se concentra em três diferentes bibliotecas que podem ser usadas como base de programação C sofisticada: Uma biblioteca RPC e uma biblioteca JSON que juntas permitem recriar muito do que fazemos nos scripts de shell, porém, usando C; enquanto uma biblioteca ZMQ nos conecta a notificações, algo que não conseguiríamos acessar até agora. (O próximo capítulo cobrirá uma biblioteca ainda mais sofisticada chamada Libwally, para finalizar esta introdução à programação do Bitcoin com C). + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Criar programas C que usam RPC para conversar com o Bitcoind; + * Criar programas C que usam ZMQ para conversar com o Bitcoind. + +Os objetivos secundários do capítulo incluem a capacidade de: + + * Entender como usar uma biblioteca RPC; + * Entender como usar uma biblioteca JSON; + * Compreender as capacidades do ZMQ; + * Entender como usar uma biblioteca ZMQ. + +## Tabela de conteúdo + + * [Seção 1: Acessando o Bitcoind usando C com Bibliotecas RPC](15_1_Accessing_Bitcoind_with_C.md) + * [Seção 2: Programando o Bitcoind usando C com Bibliotecas RPC](15_2_Programming_Bitcoind_with_C.md) + * [Seção 3: Recebendo notificações usando C com bibliotecas ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) + \ No newline at end of file diff --git a/pt/15_1_Accessing_Bitcoind_with_C.md b/pt/15_1_Accessing_Bitcoind_with_C.md new file mode 100644 index 0000000..2e97e1c --- /dev/null +++ b/pt/15_1_Accessing_Bitcoind_with_C.md @@ -0,0 +1,294 @@ + +# 15.1: Acessando o Bitcoind usando C com bibliotecas RPC + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +Você já viu uma maneira alternativa de acessar as portas RPC do Bitcoind: Usando o ``curl``, que cobrimos no [Capítulo 4 Prefácio](04_4__interlude_using_curl.md). Interagir com o ``Bitcoind`` através de uma biblioteca de RPC usando C não é diferente do que já vimos, só precisamos de boas bibliotecas para nos auxiliar. Esta seção introduz um pacote chamado ``libbitcoinrpc``, que permite acessar a porta JSON-RPC do ``bitcoind``. Ele usa uma biblioteca ``curl`` para acessar os dados e usa a biblioteca ``jansson`` para codificar e decodificar o JSON. + +## Configurando o libbitcoinrpc + +Para usar o ``libbitcoinrpc``, precisaremos instalar uma configuração básica C e os pacotes dependentes, que são ``libcurl``, ``libjansson``, e ``libuuid``. Depois faremos isso no seu servidor Standup Bitcoin (ou em qualquer outro servidor Ubuntu). + +``` +$ sudo apt-get install make gcc libcurl4-openssl-dev libjansson-dev uuid-dev +Suggested packages: + libcurl4-doc libidn11-dev libkrb5-dev libldap2-dev librtmp-dev libssh2-1-dev +The following NEW packages will be installed: + libcurl4-openssl-dev libjansson-dev uuid-dev +0 upgraded, 3 newly installed, 0 to remove and 4 not upgraded. +Need to get 358 kB of archives. +After this operation, 1.696 kB of additional disk space will be used. +Do you want to continue? [Y/n] y +``` +Agora, podemos baixar o [libbitcoinrpc no github](https://github.com/gitmarek/libbitcoinrpc/blob/master/readme.md). Vamos clonar ou pegar um arquivo zip, do jeito que preferir. + +``` +$ sudo apt-get install git +$ git clone https://github.com/gitmarek/libbitcoinrpc +``` + +> :warning: **ATENÇÃO** Uma alteração no RPC "signrawtransaction" causou uma assinatura com ``libbitcoinrpc`` para o segfault no Bitcoin 0.17 ou superior. O [Pull Request foi submetido](https://github.com/gitmarek/libbitcoinrpc/pull/1/commits) para resolver o problema, mas se ainda não tiver sido feito o merge, podemos simplesmente fazer uma simples mudança no código-fonte para ``src/bitcoinrpc_method.c`` antes de compilarmos. + +### Compilando o libbitcoinrpc. + +Antes de compilarmos e instalarmos o pacote, provavelmente precisaremos ajustar nosso ``$PATH``, para que possamos acessar o ``/sbin/ldconfig``: +``` +$ PATH="/sbin:$PATH" +``` + +Para o Ubuntu, também precisaremos ajustar o ``install_libpath`` no ``makefile`` do ``libbitcoinrpc`` para instalar no ``/usr/lib`` ao invés do ``/usr/local/lib``: + +``` +$ emacs ~/libbitcoinrpc/Makefile +... +INSTALL_LIBPATH := $(INSTALL_PREFIX)/usr/lib +``` + +(Se preferir não usar o ``/usr/lib``, precisará alterar o ``etc/ld.so.conf`` ou os arquivos dependentes de maneira apropriada... Porém, para uma configuração de teste em uma máquina de teste, acredito que isso não seja um problema). + +Da mesma forma, vamos precisar ajustar o ``install_headerpath`` no ``Makefile`` do ``libbitcoinrpc`` para instalar no caminho ``/usr/include`` ao invés do ``/usr/local/inclusve``: + +``` +... +INSTALL_HEADERPATH := $(INSTALL_PREFIX)/usr/include +``` + +Agora, podemos compilar: +``` +$ cd libbitcoinrpc +~/libbitcoinrpc$ make + +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_err.o -c src/bitcoinrpc_err.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_global.o -c src/bitcoinrpc_global.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc.o -c src/bitcoinrpc.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_resp.o -c src/bitcoinrpc_resp.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_cl.o -c src/bitcoinrpc_cl.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -o src/bitcoinrpc_method.o -c src/bitcoinrpc_method.c +gcc -fPIC -O3 -g -Wall -Werror -Wextra -std=c99 -D VERSION=\"0.2\" -shared -Wl,-soname,libbitcoinrpc.so.0 \ +src/bitcoinrpc_err.o src/bitcoinrpc_global.o src/bitcoinrpc.o src/bitcoinrpc_resp.o src/bitcoinrpc_cl.o src/bitcoinrpc_method.o \ +-o .lib/libbitcoinrpc.so.0.2 \ +-Wl,--copy-dt-needed-entries -luuid -ljansson -lcurl +ldconfig -v -n .lib +.lib: + libbitcoinrpc.so.0 -> libbitcoinrpc.so.0.2 (changed) +ln -fs libbitcoinrpc.so.0 .lib/libbitcoinrpc.so +``` +Se tudo correr bem, podemos instalar o pacote: +``` +$ sudo make install +Installing to +install .lib/libbitcoinrpc.so.0.2 /usr/local/lib +ldconfig -n /usr/local/lib +ln -fs libbitcoinrpc.so.0 /usr/local/lib/libbitcoinrpc.so +install -m 644 src/bitcoinrpc.h /usr/local/include +Installing docs to /usr/share/doc/bitcoinrpc +mkdir -p /usr/share/doc/bitcoinrpc +install -m 644 doc/*.md /usr/share/doc/bitcoinrpc +install -m 644 CREDITS /usr/share/doc/bitcoinrpc +install -m 644 LICENSE /usr/share/doc/bitcoinrpc +install -m 644 Changelog.md /usr/share/doc/bitcoinrpc +Installing man pages +install -m 644 doc/man3/bitcoinrpc*.gz /usr/local/man/man3 +``` + +## Preparando o código + +``libbitcoinrpc`` tem métodos simples e bem estruturados para conectar-se ao nosso `bitcoind`, executando chamadas RPC e decodificando a resposta. + +Para usar o ``libbitcoinrpc``, é importante certificar de que nossos arquivos do código incluam os cabeçalhos apropriados: +``` c +#include +#include +``` + +Precisaremos também vincular as bibliotecas apropriadas sempre que possamos compilar: + +``` +$ cc yourcode.c -lbitcoinrpc -ljansson -o yourcode +``` + +## Construindo a conexão + +Para construir a conexão com o servidor ``bitcoind`` é necessário alguns simples passos. + +Primeiro, inicialize a biblioteca: +``` +bitcoinrpc_global_init(); +``` +Em seguida, vamos conectar ao ``Bitcoind`` com ``bitcoinrpc_cl_init_params``. Os quatro argumentos necessários para o ``bitcoinrpc_cl_init_params`` são o nome de usuário, a senha, o endereço IP e a porta. A esta altura, você deve saber todas essas informações, já que foram necessárias para realizar o trabalho com o [curl](04_4__interlude_using_curl.md). Apenas para recordar, o endereço de IP é 127.0.0.1 e a porta 18332 devem estar corretos para a configuração padrão da testenet descrita neste documento, enquanto podemos encontrar o usuário e a senha no arquivo ``~/.bitcoin/bitcoin.conf``. +``` +$ cat bitcoin.conf +server=1 +dbcache=1536 +par=1 +maxuploadtarget=137 +maxconnections=16 +rpcuser=StandUp +rpcpassword=6305f1b2dbb3bc5a16cd0f4aac7e1eba +rpcallowip=127.0.0.1 +debug=tor +prune=550 +testnet=1 +[test] +rpcbind=127.0.0.1 +rpcport=18332 +[main] +rpcbind=127.0.0.1 +rpcport=8332 +[regtest] +rpcbind=127.0.0.1 +rpcport=18443 +``` +Com essas informações, vamos colocá-las no ``bitcoinrpc_cl_init_params``: +``` c +bitcoinrpc_cl_t *rpc_client; +rpc_client = bitcoinrpc_cl_init_params("StandUp", "6305f1b2dbb3bc5a16cd0f4aac7e1eba", "127.0.0.1", 18332); +``` + +> **MAINNET VS TESTNET:** A porta seria a 8332 caso estivéssemos usando a configuração da rede principal. + +Se o ``rpc_client`` for inicializado com sucesso, poderemos enviar os comandos do RPC. + +Mais tarde, quando tivermos feito com a conexão de ``bitcoind``, poderemos fechar da seguinte maneira: +``` c +bitcoinrpc_global_cleanup(); +``` + +### Testando o código de teste + +O código de teste pode ser encontrado [no diretório src com o nome 15_1_testbitcoin.c](src/15_1_testbitcoin.c). Vamos fazer o download para a nossa máquina TestNet e depois inserir a senha correta do RPC (e alterar o usuário RPC se não tivermos criado o servidor com StandUp). + +Podemos compilar e executar o código da seguinte maneira: +``` +$ cc testbitcoin.c -lbitcoinrpc -ljansson -o testbitcoin +$ ./testbitcoin +Successfully connected to server! +``` + +> :warning: **ATENÇÃO:** Se esquecermos de inserir a senha RPC nesta ou em qualquer outro código que possuem dependências do RPC, receberemos um misterioso ``ERROR CODE 5``. + +## Fazendo uma chamada ao RPC + +Para usarmos um método RPC usando ``libbitcoinrpc``, devemos inicializar uma variável do tipo ``bitcoinrpc_method_t``. Podemos fazer com o valor apropriado para o método que desejamos utilizar, que estão todos listados na [Referências do BitcoinRPC](https://github.com/gitmarek/libbitcoinrpc/blob/master/doc/reference.md). +``` c +bitcoinrpc_method_t *getmininginfo = NULL; +getmininginfo = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETMININGINFO); +``` +Normalmente definiríamos os parâmetros em seguida, mas o ``GetMiningInfo`` não requer parâmetros, por isso podemos pular essa parte. + +Também devemos criar outros dois objetos, um "objeto de resposta" e um "objeto de erro". Eles podem ser inicializados da seguinte forma: +``` c +bitcoinrpc_resp_t *btcresponse = NULL; +btcresponse = bitcoinrpc_resp_init(); + +bitcoinrpc_err_t btcerror; +``` +Vamos usar a variável ``rpc_client`` que aprendemos no teste anterior e vamos adicionar nosso método ``getmininginfo`` e os outros dois objetos: +``` c +bitcoinrpc_call(rpc_client, getmininginfo, btcresponse, &btcerror); +``` + +### Mostrando o retorno da chamada + +Com certeza iremos querer saber o que a RPC retornou. Para fazermos isso, vamos recuperar a saída da nossa chamada como sendo um objeto JSON com ``bitcoinrpc_resp_get`` e vamos salvá-la em um objeto padrão ``jansson``, do tipo ``json_t``: +``` c +json_t *jsonresponse = NULL; +jsonresponse = bitcoinrpc_resp_get(btcresponse); +``` +Se quisermos gerar os resultados completos da chamada RPC no JSON, podemos fazer com uma simples invocação do ``json_dumps``, da biblioteca ``jansson``: +``` c +printf("%s\n", json_dumps(j, JSON_INDENT(2))); +``` +No entanto, como agora estamos escrevendo programas completos, provavelmente iremos querer fazer um trabalho mais sutil, como retirar valores individuais do JSON para algum uso específico. A [Referência do Jansson](https6//jansson.readthedocs.Io/en/2.10/apiref.html) traz detalhes de como fazer. + +Assim como estávamos usando o [curl](04_4__interlude_using_curl.md), descobrimos que o RPC retorna um objeto JSON contendo um ``ID``, um ``error`` e, mais importante, um objeto JSON do tipo ``result``. + +A função ``json_object_get`` permite recuperar um valor (como o ``result``) de um objeto JSON usando chaves: +``` c +json_t *jsonresult = NULL; +jsonresult = json_object_get(jsonresponse,"result"); +printf("%s\n", json_dumps(jsonresult, JSON_INDENT(2))); +``` + +No entanto, provavelmente iremos querer analisar informações ainda mais profundas, para obter uma variável específica. Depois de recuperar o valor apropriado, precisaremos convertê-lo em um objeto C padrão usando a função ``JSON_*_value``. Por exemplo, para acessar um integer usamos o ``json_integer_value``: +``` c +json_t *jsonblocks = NULL; +jsonblocks = json_object_get(jsonresult,"blocks"); + +int blocks; +blocks = json_integer_value(jsonblocks); +printf("Block Count: %d\n",blocks); +``` + +> :warning: **ATENÇÃO:** É extremamente fácil ocasionar erros de segmentação no código C quando estivermos trabalhando com os objetos ``jansson`` caso fiquemos confusos com que tipo de objeto estamos recuperando. Por isso, precisamos fazer isso com cuidado usando o ``bitcoin-cli help`` para saber o que devemos esperar, e se tivermos uma falha de segmentação, primeiro precisamos analisar se nossas funções de recuperação JSON estão corretas. + +### Testando o código de informação + +Vamos recuperar o código de teste que está no [diretório src](15_1_GetMiningInfo.c). +``` +$ cc getmininginfo.c -lbitcoinrpc -ljansson -o getmininginfo +$ ./getmininginfo +Full Response: { + "result": { + "blocks": 1804406, + "difficulty": 4194304, + "networkhashps": 54842097951591.781, + "pooledtx": 127, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" + }, + "error": null, + "id": "474ccddd-ef8c-4e3f-93f7-fde72fc08154" +} + +Just the Result: { + "blocks": 1804406, + "difficulty": 4194304, + "networkhashps": 54842097951591.781, + "pooledtx": 127, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" +} + +Block Count: 1804406 +``` + +## Fazendo uma chamada RPC usando argumentos + +Mas e se a sua chamada RPC tiver argumentos? + +### Criando uma matriz JSON + +Para enviar parâmetros para a nossa chamada RPC usando ``libbitcoinrpc`` teremos que envolvê-los em uma matriz json. Como uma matriz é apenas uma simples listagem de valores, tudo o que precisamos fazer é codificar os parâmetros como elementos ordenados na matriz. + +Vamos criar a matriz JSON usando a função ``json_array do`` do ``jansson``: +``` c +json_t *params = NULL; +params = json_array(); +``` +Vamos fazer o processo inverso que fizemos para acessar valores do JSON: Vamos converter objetos no C para objetos no JSON usando as funções ``JSON_*``. Depois, vamos anexar tudo à matriz: +``` c +json_array_append_new(params,json_string(tx_rawhex)); +``` + +Observe que existem duas variantes para o comando de anexação: ``json_array_apend_new``, que acrescenta uma variável recém-criada, e ``json_array_apend``, que anexa uma variável existente. + +Esta metodologia simples ``json_array_apend_new`` servirá para a maioria dos comandos RPC com parâmetros, mas alguns dos comandos RPC exigem entradas mais complexas. Nesses casos, precisaremos criar objetos JSON ou arrays em JSON, que anexaremos ao parâmetros de array como de costume. A próxima seção contém um exemplo de como fazer isso usando o ``CrayAwTransaction``, que contém uma matriz JSON de objetos JSON para as entradas, um objeto JSON para as saídas e o parâmetro ``locktime``. + +### Atribuindo os parâmetros + +Quando criamos o parâmetro array no JSON, simplesmente o atribuímos depois de inicializar o método RPC, da seguinte maneira: +``` c +bitcoinrpc_method_set_params(rpc_method, params) +``` +Esta seção não inclui uma amostra abrangente dessa metodologia mais complexa, mas vamos vê-la em ação várias vezes no nosso primeiro programa C mais abrangente usando o RPC, na próxima seção. + +## Resumo do capítulo Acessando o Bitcoind usando C com bibliotecas RPC + +Ao vincular às bibliotecas ``BitcoinRPC`` do RPC e as bibliotecas ``jansson`` do JSON, podemos acessar facilmente o ``bitcoind`` usando chamadas RPC de uma biblioteca C. Para fazer isso, criamos uma conexão RPC, que faz as chamadas individuais de RPC, algumas delas passando alguns parâmetros. O ``jansson`` permite decodificar as respostas no formato JSON. A próxima seção demonstrará como isso pode ser usado para um programa de uso do mundo real. + +* :fire: ***Qual é o poder de C?*** O C permite que façamos o próximo passo muito além do script shell, permitindo a criação de programas mais complexos e robustos. + +## O Que Vem Depois? + +Vamos falar mais um pouco no "Conversando com o Bitcoind usando C" no capítulo [15.2: Programando o Bitcoind usando C com bibliotecas RPC](15_2_Programming_bitcoind_with_c.md). diff --git a/pt/15_2_Programming_Bitcoind_with_C.md b/pt/15_2_Programming_Bitcoind_with_C.md new file mode 100644 index 0000000..c1fdc38 --- /dev/null +++ b/pt/15_2_Programming_Bitcoind_with_C.md @@ -0,0 +1,354 @@ + +# 15.2: Programando o Bitcoind usando C com bibliotecas RPC + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +A sessão [§15.1](15_1_Accessing_Bitcoind_with_C.md) apresentou a metodologia para a criação de programas C usando bibliotecas RPC e JSON. Agora vamos mostrar o potencial dessas bibliotecas C fazendo algumas coisas um pouco mais avançadas usando o programa real do Bitcoin. + +## Planejando o código + +Esta seção irá criar uma versão simples do ``sendtoaddress``, permitindo ao usuário enviar as moedas para um endereço, desde que tenha um UTXO grande o suficiente para isso. Aqui está o que precisamos fazer: + + 1. Solicitar um endereço e uma quantia; + 2. Definir uma taxa arbitrária; + 3. Preparar nosso RPC; + 4. Encontrar um UTXO que seja grande o suficiente para pagar o valor + a taxa; + 5. Criar uma mudança de endereço; + 6. Criar uma transação bruta que envie o UTXO para o endereço e altere o endereço; + 7. Assinar a transação; + 8. Enviar a transação. + +### Planejando para o futuro + +Como este é o nosso primeiro programa C funcional, vamos mantê-lo simples (ou seja, vamos usar a filosofia, _Keep it Simple_ ou também conhecida como KISS). Se estivéssemos produzindo um programa para estar em produção, desejaríamos pelo menos os seguintes passos: + + 1. Testar e/ou higienizar as entradas; + 2. Calcular uma taxa automaticamente; + 3. Pensar logicamente sobre qual UTXO seria válido utilizar; + 4. Combinar vários UTXOs, caso seja necessário; + 5. Ficar atento a mais erros nos comandos ``libbitcoinrpc`` ou no ``jansson``; + 6. Observar se há erros nas respostas RPC. + +Se deseja continuar a expandir este exemplo, seria ótimo começar a lidar com as inadequações do programa. + +## Escrevendo o sistema de transação + +Agora estamos prontos para realizar o passo a passo do nosso plano + +### Etapa 1: Solicitando um endereço e uma quantia + +Inserir as informações é bem simples se usarmos os argumentos na linha de comando: +``` c +if(argc != 3) { + + printf("ERROR: Only %i arguments! Correct usage is '%s [recipient] [amount]'\n",argc-1,argv[0]); + exit(-1); + +} + +char *tx_recipient = argv[1]; +float tx_amount = atof(argv[2]); + +printf("Sending %4.8f BTC to %s\n",tx_amount,tx_recipient); +``` + +> :aviso: **ATENÇÃO:** Um programa real precisaria de uma higienização muito melhor dessas variáveis. + +### Etapa 2: Definindo uma taxa arbitrária + +Este exemplo colocamos uma taxa arbitrária de 0.0005 BTC para garantir que as transações do teste sejam processadas rapidamente: + +``` c +float tx_fee = 0.0005; +float tx_total = tx_amount + tx_fee; +``` + +> :warning: **ATENÇÃO:** Um programa real calcularia uma taxa que minimizasse o custo, garantindo que a velocidade fosse aquela que o remetente estivesse disposto a utilizar. + +### Etapa 3: Preparando nosso RPC + +Obviamente, precisaremos preparar todas as nossas variáveis novamente, conforme discutido na sessão [§15.1: Acessando o Bitcoind usando C](15_1_Accessing_Bitcoind_with_C.md). Também precisaremos inicializar a nossa biblioteca, conectar o cliente RPC e preparar nosso objeto de resposta: +``` c +bitcoinrpc_global_init(); +rpc_client = bitcoinrpc_cl_init_params("bitcoinrpc", "YOUR-RPC-PASSWD", "127.0.0.1", 18332); +btcresponse = bitcoinrpc_resp_init(); +``` + +### Etapa 4: Encontrando um UTXO + +Para encontrar um UTXO, precisaremos chamar a função RPC ``listunspent``: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_LISTUNSPENT); +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +``` + +No entanto, o verdadeiro trabalho consiste em decodificar a resposta. Na seção anterior vimos que a biblioteca ``jansson`` era "um tanto quanto desajeitada" e esta é a razão: Precisamos criar (e limpar) um conjunto muito grande de objetos ``json_t`` para descobrir o que queremos. + +Primeiro, precisamos nos recuperar o campo ``result`` do JSON: +``` c +json_t *lu_response = NULL; +json_t *lu_result = NULL; + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); +``` + +> :warning: **ATENÇÃO:** Só obteremos um resultado se não houver nenhum erro. Aqui temos um momento para melhorar nossa verificação de erros no código que iremos colocar em produção. + +Em seguida, vamos fazer um laço, examinando cada transação que não foi gasta, que aparece como um elemento em sua matriz do resultado JSON: +``` c +int i; + +const char *tx_id = 0; +int tx_vout = 0; +double tx_value = 0.0; + +for(i = 0 ; i < json_array_size(lu_result) ; i++) { + + json_t *lu_data = NULL; + lu_data = json_array_get(lu_result, i); + + json_t *lu_value = NULL; + lu_value = json_object_get(lu_data,"amount"); + tx_value = json_real_value(lu_value); +``` + +O UTXO é grande o suficiente para pagar sua transação? Se sim, pegue-o! + +> :warning: **ATENÇÃO:** Um programa em produção pensaria com mais cuidado sobre qual UTXO utilizar, com base no tamanho e em outros fatores. Provavelmente não pegaria apenas o primeiro mais simples e pronto. + +``` c + if(tx_value > tx_total) { + + json_t *lu_txid = NULL; + lu_txid = json_object_get(lu_data,"txid"); + tx_id = strdup(json_string_value(lu_txid)); + + json_t *lu_vout = NULL; + lu_vout = json_object_get(lu_data,"vout"); + tx_vout = json_integer_value(lu_vout); + + json_decref(lu_value); + json_decref(lu_txid); + json_decref(lu_vout); + json_decref(lu_data); + break; + + } +``` +Você também deve limpar os principais elementos do JSON: +``` c +} + +json_decref(lu_result); +json_decref(lu_response); +``` + +> :warning: **ATENÇÃO:** Um programa em produção também se certificaria de que os UTXOs são passíveis de serem `gastos`. + +Se não encontramos nenhum UTXOs grande o suficiente, teremos que relatar este infortúnio ao usuário... E talvez, sugerir que ele deva usar um programa melhor, que irá mesclar os UTXOs de maneira correta. +``` c +if(!tx_id) { + + printf("Very Sad: You don't have any UTXOs larger than %f\n",tx_total); + exit(-1); +} +``` + +> **ATENÇÃO** Um programa em produção usaria sub-rotinas para este tipo de pesquisa, de forma que pudéssemos chamar vários RPCs de uma biblioteca de funções C. Vamos apenas colocar tudo em um `main` como parte da nossa filosofia KISS. + +### Etapa 5: Criando um endereço de troco + +Repita a metodologia padrão de pesquisa RPC para obter um endereço de troco: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_GETRAWCHANGEADDRESS); + +if(!rpc_method) { + + printf("ERROR: Unable to initialize listunspent method!\n"); + exit(-1); + +} + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); + +if(btcerror.code != BITCOINRPCE_OK) { + +printf("Error: listunspent error code %d [%s]\n", btcerror.code,btcerror.msg); + + exit(-1); + +} + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); +char *changeaddress = strdup(json_string_value(lu_result)); +``` +A única diferença é quais informações específicas são extraídas do objeto JSON. + +> :warning: **ATENÇÃO:** Aqui temos uma sub-rotina que seria bem legal: Abstrair toda a inicialização e chamada do método RPC. + +### Etapa 6: Criando uma transação bruta + +Criar a transação bruta real é outra parte complicada da programação da substituição do ``sendtoaddress``. Isso porque requer a criação de um objeto JSON complexo como parâmetro. + +Para criarmos esses parâmetros corretamente, precisaremos revisar o que o RPC ``createrawtransaction`` espera que passemos como argumento. Felizmente, isso é fácil de determinar usando a funcionalidade ``bitcoin-cli help``: +``` +$ bitcoin-cli help createrawtransaction +createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,"data":"hex",...} ( locktime ) +``` + +Para relembrar, as entradas serão uma matriz JSON contendo um objeto JSON para cada UTXO. Então, as saídas estarão todas em um objeto JSON. É mais fácil criar esses elementos JSON de dentro para fora, usando os comandos ``jansson``. + +#### Etapa 6.1: Criando os parâmetros de entrada + +Para criar o objeto de entrada para nosso UTXO, vamos usar o ``json_object`` e preencher com os valores-chave usando ``json_object_set_new`` (para referências recém-criadas) ou ``json_object_set`` (para referências já existentes): +``` c +json_t *inputtxid = NULL; +inputtxid = json_object(); + +json_object_set_new(inputtxid,"txid",json_string(tx_id)); +json_object_set_new(inputtxid,"vout",json_integer(tx_vout)); +``` + +Pode-se notar que teremos que traduzir novamente cada tipo de variável C em um tipo de variável JSON usando a função apropriada, como ``json_string`` ou ``json_integer``. + +Para criar o array de entrada para todos os UTXOs, vamos usar o ``json_array`` e, em seguida, preenchê-lo com os objetos usando o ``json_array_append``: +``` c +json_t *inputparams = NULL; +inputparams = json_array(); +json_array_append(inputparams,inputtxid); +``` + +#### Etapa 6.2: Criando os parâmetros de saída + +Para criar a matriz de saída para a transação, vamos seguir o mesmo processo, criando um objeto JSON com ``json_object`` e, em seguida, vamos preenchê-lo com o ``json_object_set``: +``` c +json_t *outputparams = NULL; +outputparams = json_object(); + +char tx_amount_string[32]; +sprintf(tx_amount_string,"%.8f",tx_amount); +char tx_change_string[32]; +sprintf(tx_change_string,"%.8f",tx_value - tx_total); + +json_object_set(outputparams, tx_recipient, json_string(tx_amount_string)); +json_object_set(outputparams, changeaddress, json_string(tx_change_string)); +``` + +> :warning: **ATENÇÃO:** É possível pensar que teremos que inserir os valores do Bitcoin como sendo números, usando a função ``json_real``. Infelizmente, isso expõe um dos maiores problemas com a integração da biblioteca ``jansson`` e o Bitcoin. O Bitcoin só é válido até oito dígitos depois da casa decimal. Devemos nos lembrar que 0,00000001 BTC é um satoshi, e essa é a menor divisão possível de um Bitcoin. O tipo ``double`` no C oferecem mais dígitos do que precisamos, embora sejam frequentemente imprecisos depois das oito casas decimais. Se tentarmos convertê-los diretamente do nosso valor ``double`` no C (ou de um tipo ``float``, neste caso) para um valor Bitcoin, a imprecisão frequentemente criará um valor Bitcoin com mais de oito dígitos. Antes da versão Bitcoin Core 0.12, isso não era problema, e podíamos usar a função ``json_real``. Mas à partir dessa versão, se tentarmos usar a função ``createrawtransaction`` com mais do que oito dígitos, obteremos um erro e a transação não será criada. Como resultado, se o valor do Bitcoin _sempre_ se tornar um ``double`` ou ``float``, devemos deixar com apenas oito casas decimais antes de transformá-lo em uma ``string``. Obviamente, isso é um erro, portanto, certifique-se disso para que o código continue funcionando nas versões mais novas do Bitcoin Core. + +#### Etapa 6.3: Criando a Matriz de Parâmetros + +Para terminarmos de criar os parâmetros, só precisaremos agrupá-los em uma matriz JSON: +``` c +json_t *params = NULL; +params = json_array(); +json_array_append(params,inputparams); +json_array_append(params,outputparams); +``` + +#### Etapa 6.4: Fazendo a chamada ao RPC + +Vamos usar o método normal para criar uma chamada ao RPC: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_CREATERAWTRANSACTION); +``` +Agora, porém, devemos adicionar os nossos parâmetros. Isso pode ser feito facilmente com a função ``bitcoinrpc_method_set_params``: +``` c +if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf(stderr, "Error: Could not set params for createrawtransaction"); + +} +``` +Depois, é só executar o RPC e obter os resultados: +``` c +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); + +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); + +char *tx_rawhex = strdup(json_string_value(lu_result)); +``` +### Etapa 7. Assinando a transação + +É muito mais fácil atribuir um parâmetro simples a uma função. Basta criar uma matriz JSON e, em seguida, atribuir o parâmetro à matriz: +``` c +params = json_array(); +json_array_append_new(params,json_string(tx_rawhex)); +``` +Por fim, vamos assinar a transação seguindo o rigamarole típico para criar uma chamada RPC: +``` c +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SIGNRAWTRANSACTION); +if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf(stderr, "Error: Could not set params for signrawtransaction"); + +} + +json_decref(params); + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +lu_response = bitcoinrpc_resp_get(btcresponse); +``` +Novamente, usar a função ``jansson`` para acessar a saída pode ser complicado. Devemos lembrar que ``hex`` é parte de um objeto JSON, não um resultado independente, como era quando criamos a transação bruta. Claro, sempre podemos acessar essas informações a partir da ajuda da linha de comando: ``bitcoin-cli help signrawtransaction`` +``` c +lu_result = json_object_get(lu_response,"result"); +json_t *lu_signature = json_object_get(lu_result,"hex"); +char *tx_signrawhex = strdup(json_string_value(lu_signature)); +json_decref(lu_signature); +``` +> :warning: ***ATENÇÃO:*** Um programa em produção obviamente iria testar cuidadosamente a resposta de cada comando RPC para se certificar de que não teria erros. Isso é ainda mais verdadeiro para a função ``signrawtransaction``, porque podemos acabar com uma transação parcialmente assinada. Ou ainda pior, se não verificarmos os erros no objeto JSON, veremos apenas o ``hex`` e não iremos saber que ele não está assinado ou se está parcialmente assinado. + +### Etapa 8. Enviando a transação + +Agora podemos enviar a transação, usando todas as técnicas aprendidas anteriormente: +``` c +params = json_array(); +json_array_append_new(params,json_string(tx_signrawhex)); + +rpc_method = bitcoinrpc_method_init(BITCOINRPC_METHOD_SENDRAWTRANSACTION); + +if(bitcoinrpc_method_set_params(rpc_method, params) != BITCOINRPCE_OK) { + + fprintf(stderr, "Error: Could not set params for sendrawtransaction"); + +} + +json_decref(params); + +bitcoinrpc_call(rpc_client, rpc_method, btcresponse, &btcerror); +lu_response = bitcoinrpc_resp_get(btcresponse); +lu_result = json_object_get(lu_response,"result"); + +char *tx_newid = strdup(json_string_value(lu_result)); + +printf("Txid: %s\n",tx_newid); +``` + +O código inteiro, com um _pouco_ mais verificação de erros, está disponível no Apêndice. + +## Testando o código + +O código completo pode ser encontrado no [diretório src/](src/15_2_sendtoaddress.c). + +Compile-o como de costume: +``` +$ cc sendtoaddress.c -lbitcoinrpc -ljansson -o sendtoaddress +``` +Agora, é possível utilizá-lo para enviar fundos para um endereço: + +``` +./sendtoaddress tb1qynx7f8ulv4sxj3zw5gqpe56wxleh5dp9kts7ns .001 +Txid: b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2 +``` +Você pode ver as informações sobre esta transação que enviamos clicando [aqui](https://mempool.space/pt/testnet/tx/b93b19396f8baa37f5f701c7ca59d3128144c943af5294aeb48e3eb4c30fa9d2/). + +## Resumo do Programando o Bitcoind usando C com bibliotecas RPC + +Com acesso a uma biblioteca C, podemos criar programas com muito mais recursos quando comparados aos scripts no shell. Mas isso pode dar muito trabalho! Mesmo com 316 linhas de código, o ``sendtoaddress.c`` não cobre todos os detalhes necessários para transacionar bitcoins de forma segura e inteligente. + +## O Que Vem Depois? + +Aprenda mais sobre "Programando o Bitcoind usando C" na próxima sessão [15.3: Recebendo notificações usando C com a biblioteca ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md). \ No newline at end of file diff --git a/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md new file mode 100644 index 0000000..fe166ac --- /dev/null +++ b/pt/15_3_Receiving_Bitcoind_Notifications_with_C.md @@ -0,0 +1,155 @@ + +# 15.3 Recebendo notificações usando C com a biblioteca ZMQ + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um rascunho que pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +As sessões [§15.1](15_1_Accessing_Bitcoind_with_C.md) e [§15.2](15_2_Programming_Bitcoind_with_C.md) introduziram as bibliotecas RPC e JSON no C e, também mostrou uma das vantagens de acessar os comandos RPC do Bitcoin por meio de uma linguagem de programação: A capacidade de criar programas razoavelmente complexos. Este capítulo apresenta uma terceira biblioteca, a [ZMQ](http://zeromq.org/) e, ao fazer isso, revela outra vantagem: A capacidade de monitorar as notificações. Iremos usá-la para codificar para ouvirmos a blockchain. + +> :book: ***O que é ZMQ?*** O ZeroMQ (ZMQ) é uma biblioteca de mensagens assíncronas de alto desempenho que fornece uma fila de mensagens. A biblioteca oferece suporte a padrões de mensagens comuns (pub/sub, request/reply, client/server e outros) em uma variedade de transportes (TCP, in-process, inter-process, multicast, WebSocket e mais), tornando mensagens entre processos tão simples quanto mensagens entre threads. Podemos encontrar mais detalhes sobre as notificações do ZMQ e outros tipos de mensagens [neste repositório](https://github.com/Actinium-project/ChainTools/blob/master/docs/chainlistener.md). + +## Configurando o ZMQ + +Antes de podemos ouvir a blockchain, precisaremos configurar o ``bitcoind`` para permitir as notificações ZMQ. Por isso, precisamos instalar a biblioteca ZMQ para tirar proveito dessas notificações. + +### Configurando o ``bitcoind`` para usar o ZMQ + +O Bitcoin Core está pronto para ZMQ, mas devemos especificar os endpoints do ZMQ. O ZeroMQ publish-sockets prefixa cada item de dados com um prefixo de tópico arbitrário que permite aos clientes assinantes solicitarem apenas os itens com um prefixo correspondente. Existem atualmente quatro tópicos suportados pelo ``bitcoind``: +``` +$ bitcoind --help | grep zmq | grep address + -zmqpubhashblock=
+ -zmqpubhashtx=
+ -zmqpubrawblock=
+ -zmqpubrawtx=
+``` + +Podemos executar o ``bitcoind`` com argumentos de linha de comando para endpoints ZMQ, como mostrado acima, mas também podemos criar um endpoint acessível adicionando linhas apropriadas ao nosso arquivo ``~/.bitcoin/bitcoin.conf`` e reiniciando o sistema. + +``` +zmqpubrawblock=tcp://127.0.0.1:28332 +zmqpubrawtx=tcp://127.0.0.1:28333 +``` +Podemos então testar se os nossos endpoints estão funcionando usando o RPC ``getzmqnotifications``: + +``` +$ bitcoin-cli getzmqnotifications +[ + { + "type": "pubrawblock", + "address": "tcp://127.0.0.1:28332", + "hwm": 1000 + }, + { + "type": "pubrawtx", + "address": "tcp://127.0.0.1:28333", + "hwm": 1000 + } +] +``` +Nosso ``bitcoind`` agora irá emitir as notificações ZMQ + +### Instalando o ZMQ + +Para aproveitar essas notificações, precisamos de uma biblioteca ZMQ para usar com o C, portanto, estaremos usando uma nova biblioteca ZMQ ao invés da biblioteca ``libbitcoinrpc`` nesta seção, mas no futuro, podemos combinar ambas. + +Felizmente, as bibliotecas ZMQ estão disponíveis por meio de pacotes Debian padrão: +``` +$ sudo apt-get install libzmq3-dev +$ sudo apt-get install libczmq-dev +``` +Agora estamos pronto para escrever o código! + +## Escrevendo o programa de notificação + +O programa C à seguir é um cliente simples que se inscreve em um ponto da conexão ZMQ servido pelo ``bitcoind`` e lê as mensagens recebidas. + +O programa requer dois parâmetros: O primeiro é o "servidor", que é o ponto de conexão TCP exposto pelo ``bitcoind``. O segundo é o "tópico", que atualmente é o ``zmqpubhashblock``,``zmqpubhashtx``, ``zmqpubrawblock`` ou ``zmqpubrawtx``. O tópico precisa ter suporte do ``bitcoin.conf`` e o endereço IP e a porta do servidor devem corresponder ao que está definido no arquivo de configuração. + +``` c +#include +int main(int argc, char ** argv) { + + char *zmqserver; + char *topic; + + if(argc < 3) { + printf("\nUSAGE:\nchainlistener \n\n"); + return 0; + } else { + zmqserver = argv[1]; + topic = argv[2]; + } +``` +Abriremos um soquete ZMQ para o servidor e para o tópico definido: +``` c + zsock_t *socket = zsock_new_sub(zmqserver, topic); + assert(socket); +``` +Depois, vamos esperar: +``` c + while(1) { + zmsg_t *msg; + int rc = zsock_recv(socket, "m", &msg); + assert(rc == 0); + + char *header = zmsg_popstr(msg); + zframe_t *zdata = zmsg_pop(msg); + unsigned int *no = (unsigned int*)zmsg_popstr(msg); + + char *data = zframe_strhex(zdata); + int len = zframe_size(zdata); + printf("Size: %d\n", len); + printf("Data: %s", data); + printf("\nNo: %d\n", *no); + + free(header); + free(data); + free(no); + free(zdata); + zmsg_destroy(&msg); + sleep(1); + } +``` +Enquanto esperamos, observamos as mensagens no soquete ZMQ. Sempre que recebermos uma mensagem, iremos retirá-la da pilha, relatando o número, comprimento e, o os dados que foram importante para nós. + +É isso! + +Claro, quando terminar o processo, precisamos limpar tudo: +``` c + zsock_destroy(&socket); + return 0; +} +``` + +### Testando o código de notificação + +O código-fonte completo está no [diretório src/](src/15_3_chainlistener.c) como de costume. Precisamos compilá-lo: +``` +$ cc -o chainlistener chainlistener.c -I/usr/local/include -L/usr/local/lib -lzmq -lczmq +``` +Depois, podemos executá-lo com os tópicos e endereços que definimos no nosso ``bitcoin.conf``: +``` +$ ./chainlistener tcp://127.0.0.1:28333 rawtx +Size: 250 +Data: 02000000000101F5BD2032E5A9E6650D4E411AD272E391F26AFC3C9102B7C0C7444F8F74AE86010000000017160014AE9D51ADEEE8F46ED2017F41CD631D210F2ED9C5FEFFFFFF0203A732000000000017A9147231060F1CDF34B522E9DB650F44EDC6C0714E4C8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100AE316D5F21657E3525271DE39EB285D8A0E89A20AB6413824E88CE47DCD0EFE702202F61E10C2A8F4A7125D5EB63AEF883D8E3584A0ECED0D349283AABB6CA5E066D0121035A77FE575A9005E3D3FF0682E189E753E82FA8BFF0A20F8C45F06DC6EBE3421079111B00 +No: 67 +Size: 249 +Data: 0200000000010165C986992F7DAD22BBCE3FCF0BF546EDBC3C599618B04CFA22D9E64EF0CE4C030000000017160014B58E0A5CD68B249F1C407E9AAE9CD0332AAA3067FEFFFFFF02637932000000000017A914CCC47261489036CB6B9AA610857793FF5752E5378710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC0247304402206CCC3F3B4BE01D4E532A01C2DC6BC3B53E4FFB6B494C8B87DD603EFC648A159902201653841E8B16A814DC375129189BB7CF01CFF7D269E91178645B6A97F5C7F4F10121030E20F3D2F172281B8DC747F007DF24B352248AC09E48CA64016942A8F01D317079111B00 +No: 68 +Size: 250 +Data: 02000000000101E889CFC1FFE127BA49F6C1011388606A194109AE1EDAAB9BEE215E123C14A7920000000017160014577B0B3C2BF91B33B5BD70AE9E8BD8144F4B87E7FEFFFFFF02C34B32000000000017A914A9F1440402B46235822639C4FD2F78A31E8D269E8710270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC02483045022100B46318F53E1DCE63E7109DB4FA54AF40AADFC2FEB0E08263756BC3B7A6A744CB02200851982AF87DBABDC3DFC3362016ECE96AECFF50E24D9DCF264AE8966A5646FE0121039C90FCB46AEA1530E5667F8FF15CB36169D2AD81247472F236E3A3022F39917079111B00 +No: 69 +Size: 250 +Data: 0200000000010137527957C9AD6CFF0C9A74597E6EFCD7E1EBD53E942AB2FA34A831046CA11488000000001716001429BFF05B3CD79E9CCEFDB5AE82139F72EB3E9DB0FEFFFFFF0210270000000000001976A914262437B129CF8592AB2EDC59C07D19C57729F72888AC231E32000000000017A9146C8D5FE29BFDDABCED0D6F4D8E82DCBFD9D34A8B8702483045022100F259846BAE29EB2C7A4AD711A3BC6109DE69AE91E35B14CA2742157894DD9760022021464E09C00ABA486AEAA0C49FEE12D2850DC03F57F04A1A9E2CC4D0F4F1459C012102899F24A9D60132F4DD1A5BA6DCD1E4E4B6C728927BA482C2C4E511679F60CA5779111B00 +No: 70 +....... +``` + +### Resumo do capítulo Recebendo Notificações Usando C com a Biblioteca ZMQ + +Ao usar a estrutura ZMQ, podemos receber notificações facilmente, inscrevendo-as em um ponto de conexão exposto pelo ``bitcoind`` através do nosso arquivo de configuração. + +> :fire: ***Qual é o poder das notificações?*** Com as notificações, não dependemos mais dos usuários para emitir os comandos. Ou seja, podemos criar programas que monitoram o blockchain do Bitcoin e tomar as ações apropriadas quando certas coisas ocorrem. Isso, por sua vez, pode ser utilizado juntamente com os comandos RPC que programamos nas seções anteriores. Este também é um grande passo além do que poderíamos fazer com os scripts shell: Certamente, podemos criar scripts shell que fica ouvindo infinitamente, mas existem outras linguagens de programação que possuem ferramentas melhores para isso. + +## O Que Vem Depois? + +Saiba mais sobre "como Programar com RPC" no [Capítulo 16: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md). \ No newline at end of file From f82b60e419eb5edb97706ffa1b4ace501a44e1f4 Mon Sep 17 00:00:00 2001 From: Luke Pavksy <85752004+lukedevj@users.noreply.github.com> Date: Fri, 25 Jun 2021 19:48:15 -0300 Subject: [PATCH 26/50] Chapter 15 Translated wait for review --- pt/03_0_Understanding_Your_Bitcoin_Setup.md | 31 ++ pt/03_1_Verifying_Your_Bitcoin_Setup.md | 103 ++++++ pt/03_2_Knowing_Your_Bitcoin_Setup.md | 315 ++++++++++++++++++ pt/03_3_Setting_Up_Your_Wallet.md | 131 ++++++++ ..._Interlude_Using_Command-Line_Variables.md | 40 +++ 5 files changed, 620 insertions(+) create mode 100644 pt/03_0_Understanding_Your_Bitcoin_Setup.md create mode 100644 pt/03_1_Verifying_Your_Bitcoin_Setup.md create mode 100644 pt/03_2_Knowing_Your_Bitcoin_Setup.md create mode 100644 pt/03_3_Setting_Up_Your_Wallet.md create mode 100644 pt/03_3__Interlude_Using_Command-Line_Variables.md diff --git a/pt/03_0_Understanding_Your_Bitcoin_Setup.md b/pt/03_0_Understanding_Your_Bitcoin_Setup.md new file mode 100644 index 0000000..865b693 --- /dev/null +++ b/pt/03_0_Understanding_Your_Bitcoin_Setup.md @@ -0,0 +1,31 @@ +# Capítulo três: Compreendendo a configuração do seu node Bitcoin + +Agora que você está pronto para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que você entenda a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. + +Neste e nos próximos capítulos, presumimos que você tenha uma VPS com Bitcoin instalado, executando `bitcoind`. Também presumimos que você está conectado à testnet, permitindo o acesso a bitcoins sem usar fundos reais. Você pode fazer isso com Bitcoin Standup em linode.com, por [2.1: Configurando um Bitcoin-Core no VPS c Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou por outros métodos, por [2.2: Configurando um node Bitcoin Core por outros métodos](02_2_Setting_Up_Bitcoin_Core_Other.md). + +## Objetivos deste Capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Demonstrar que o node Bitcoin está instalado e atualizado + * Criar um endereço para receber fundos de Bitcoin + * Usar os comandos básicos da carteira + * Criar um endereço a partir de um descritor + +Os objetivos de apoio incluem a capacidade de: + + * Compreender o layout básico do arquivo Bitcoin + * Usar comandos informativos básicos + * Entender o que é um endereço Bitcoin + * Entender o que é uma carteira + * Entender como importar endereços + +## Índice + +* [Seção Um: Verificando a configuração do seu node Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) +* [Seção Dois: conhecendo a configuração do seu node Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) +* [Seção Três: Configurando sua carteira](03_3_Setting_Up_Your_Wallet.md) + * [Usando variável de linha de comando](03_3__Interlude_Using_Command-Line_Variables.md) +* [Seção Quatro: Recebendo uma transação](03_4_Receiving_a_Transaction.md) +* [Seção Cinco: Entendendo um descritor](03_5_Understanding_the_Descriptor.md) \ No newline at end of file diff --git a/pt/03_1_Verifying_Your_Bitcoin_Setup.md b/pt/03_1_Verifying_Your_Bitcoin_Setup.md new file mode 100644 index 0000000..2997ef3 --- /dev/null +++ b/pt/03_1_Verifying_Your_Bitcoin_Setup.md @@ -0,0 +1,103 @@ +# 3.1: Verificando a configuração do seu node Bitcoin + +Antes de começar a brincar com Bitcoin, você deve se certificar de que tudo está configurado corretamente. + +## Crie seus aliases + +Sugerimos a criação de alguns aliases para facilitar o uso do Bitcoin + +Você pode fazer isso colocando-os em seu `.bash_profile`,` .bashrc` ou `.profile`. +``` +cat >> ~/.bash_profile < :book: ***O que é a altura do bloco?*** A altura do bloco é a distância que um bloco particular está do bloco de gênese. A altura do bloco atual é a altura do bloco mais recente adicionado a um blockchain. + +Você pode fazer isso olhando para um explorador, como [Mempool Space Explorer](https://mempool.space/pt/testnet). O número mais recente corresponde ao `getblockcount`? Se sim, você está atualizado. + +Se você quiser que um alias veja tudo de uma vez, o seguinte funciona atualmente para Testnet, mas pode desaparecer em algum momento no futuro: +``` +$ cat >> ~/.bash_profile << EOF +alias btcblock="echo \\\`bitcoin-cli getblockcount 2>&1\\\`/\\\`wget -O - https://blockstream.info/testnet/api/blocks/tip/height 2> /dev/null | cut -d : -f2 | rev | cut -c 1- | rev\\\`" +EOF +$ source .bash_profile +$ btcblock +1804372/1804372 +``` + +> :link: **TESTNET vs MAINNET:** Lembre-se de que este tutorial geralmente assume que você está usando testnet. Se você estiver usando a mainnet, pode recuperar a altura do bloco atual com: `wget -O - https://mempool.space/testnet/api/blocks/tip/height 2> /dev/ null`. Você pode substituir a última metade do alias `btblock` (após `/`) por isso. + +Se você não está atualizado, mas seu `getblockcount` está aumentando, não há problema. O tempo total de download pode levar de uma hora a várias horas, dependendo da configuração. + +## Opcional: Conheça os tipos de servidores + +> **TESTNET vs MAINNET:** Ao configurar seu node Bitcoin, você escolhe criá-lo como um Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração de rede de teste, vale a pena entender como você pode acessar e usar os outros tipos de configuração - mesmo todos na mesma máquina! Mas, se você for um usuário iniciante, pule isso, pois não é necessário para uma configuração básica. + +O tipo de configuração é controlado principalmente por meio do arquivo `~/.bitcoin/bitcoin.conf`. Se você estiver executando o testnet, provavelmente contém esta linha: +``` +testnet=1 +``` +Se você estiver executando o regtest, provavelmente contém esta linha: +``` +regtest=1 +``` +No entanto, se você deseja executar vários tipos diferentes de nós simultaneamente, deve deixar o sinalizador testnet (ou regtest) fora de seu arquivo de configuração. Você pode então escolher se está usando mainnet, testnet ou regtest toda vez que executar bitcoind ou bitcoin-cli. + +Aqui está um conjunto de aliases que tornariam isso mais fácil, criando um alias específico para iniciar e parar o bitcoind, para ir para o diretório bitcoin e para executar bitcoin-cli, para cada mainnet (que não tem sinalizadores extras), o testnet (que é -testnet), ou seu regtest (que é -regtest). +``` +cat >> ~/.bash_profile < :link: **TESTNET vs MAINNET:** Se você estiver usando mainnet, então _tudo_ será colocado no diretório principal `~/.bitcoin`. Então se você estiver usando mainnet, testnet e regtest, você verá que `~/.bitcoin` contém seu arquivo de configuração e seus dados mainnet, o diretório` ~/.bitcoin/testnet3` contém seus dados testnet, e o diretório `~/.bitcoin/regtest` contém seus dados de regtest. + +## Conheça os comandos do Bitcoin-cli + +A maior parte do seu trabalho inicial será feito com o comando `bitcoin-cli`, que oferece uma interface fácil para o `bitcoind`. Se você quiser mais informações sobre seu uso, basta executá-lo com o argumento `help`. Sem nenhum outro argumento, ele mostrara todos os comandos possíveis: +``` +$ bitcoin-cli help +== Blockchain == +getbestblockhash +getblock "blockhash" ( verbosity ) +getblockchaininfo +getblockcount +getblockfilter "blockhash" ( "filtertype" ) +getblockhash height +getblockheader "blockhash" ( verbose ) +getblockstats hash_or_height ( stats ) +getchaintips +getchaintxstats ( nblocks "blockhash" ) +getdifficulty +getmempoolancestors "txid" ( verbose ) +getmempooldescendants "txid" ( verbose ) +getmempoolentry "txid" +getmempoolinfo +getrawmempool ( verbose ) +gettxout "txid" n ( include_mempool ) +gettxoutproof ["txid",...] ( "blockhash" ) +gettxoutsetinfo +preciousblock "blockhash" +pruneblockchain height +savemempool +scantxoutset "action" ( [scanobjects,...] ) +verifychain ( checklevel nblocks ) +verifytxoutproof "proof" + +== Control == +getmemoryinfo ( "mode" ) +getrpcinfo +help ( "command" ) +logging ( ["include_category",...] ["exclude_category",...] ) +stop +uptime + +== Generating == +generatetoaddress nblocks "address" ( maxtries ) +generatetodescriptor num_blocks "descriptor" ( maxtries ) + +== Mining == +getblocktemplate ( "template_request" ) +getmininginfo +getnetworkhashps ( nblocks height ) +prioritisetransaction "txid" ( dummy ) fee_delta +submitblock "hexdata" ( "dummy" ) +submitheader "hexdata" + +== Network == +addnode "node" "command" +clearbanned +disconnectnode ( "address" nodeid ) +getaddednodeinfo ( "node" ) +getconnectioncount +getnettotals +getnetworkinfo +getnodeaddresses ( count ) +getpeerinfo +listbanned +ping +setban "subnet" "command" ( bantime absolute ) +setnetworkactive state + +== Rawtransactions == +analyzepsbt "psbt" +combinepsbt ["psbt",...] +combinerawtransaction ["hexstring",...] +converttopsbt "hexstring" ( permitsigdata iswitness ) +createpsbt [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime replaceable ) +createrawtransaction [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime replaceable ) +decodepsbt "psbt" +decoderawtransaction "hexstring" ( iswitness ) +decodescript "hexstring" +finalizepsbt "psbt" ( extract ) +fundrawtransaction "hexstring" ( options iswitness ) +getrawtransaction "txid" ( verbose "blockhash" ) +joinpsbts ["psbt",...] +sendrawtransaction "hexstring" ( maxfeerate ) +signrawtransactionwithkey "hexstring" ["privatekey",...] ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +testmempoolaccept ["rawtx",...] ( maxfeerate ) +utxoupdatepsbt "psbt" ( ["",{"desc":"str","range":n or [n,n]},...] ) + +== Util == +createmultisig nrequired ["key",...] ( "address_type" ) +deriveaddresses "descriptor" ( range ) +estimatesmartfee conf_target ( "estimate_mode" ) +getdescriptorinfo "descriptor" +signmessagewithprivkey "privkey" "message" +validateaddress "address" +verifymessage "address" "signature" "message" + +== Wallet == +abandontransaction "txid" +abortrescan +addmultisigaddress nrequired ["key",...] ( "label" "address_type" ) +backupwallet "destination" +bumpfee "txid" ( options ) +createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse ) +dumpprivkey "address" +dumpwallet "filename" +encryptwallet "passphrase" +getaddressesbylabel "label" +getaddressinfo "address" +getbalance ( "dummy" minconf include_watchonly avoid_reuse ) +getbalances +getnewaddress ( "label" "address_type" ) +getrawchangeaddress ( "address_type" ) +getreceivedbyaddress "address" ( minconf ) +getreceivedbylabel "label" ( minconf ) +gettransaction "txid" ( include_watchonly verbose ) +getunconfirmedbalance +getwalletinfo +importaddress "address" ( "label" rescan p2sh ) +importmulti "requests" ( "options" ) +importprivkey "privkey" ( "label" rescan ) +importprunedfunds "rawtransaction" "txoutproof" +importpubkey "pubkey" ( "label" rescan ) +importwallet "filename" +keypoolrefill ( newsize ) +listaddressgroupings +listlabels ( "purpose" ) +listlockunspent +listreceivedbyaddress ( minconf include_empty include_watchonly "address_filter" ) +listreceivedbylabel ( minconf include_empty include_watchonly ) +listsinceblock ( "blockhash" target_confirmations include_watchonly include_removed ) +listtransactions ( "label" count skip include_watchonly ) +listunspent ( minconf maxconf ["address",...] include_unsafe query_options ) +listwalletdir +listwallets +loadwallet "filename" +lockunspent unlock ( [{"txid":"hex","vout":n},...] ) +removeprunedfunds "txid" +rescanblockchain ( start_height stop_height ) +sendmany "" {"address":amount} ( minconf "comment" ["address",...] replaceable conf_target "estimate_mode" ) +sendtoaddress "address" amount ( "comment" "comment_to" subtractfeefromamount replaceable conf_target "estimate_mode" avoid_reuse ) +sethdseed ( newkeypool "seed" ) +setlabel "address" "label" +settxfee amount +setwalletflag "flag" ( value ) +signmessage "address" "message" +signrawtransactionwithwallet "hexstring" ( [{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex","witnessScript":"hex","amount":amount},...] "sighashtype" ) +unloadwallet ( "wallet_name" ) +walletcreatefundedpsbt [{"txid":"hex","vout":n,"sequence":n},...] [{"address":amount},{"data":"hex"},...] ( locktime options bip32derivs ) +walletlock +walletpassphrase "passphrase" timeout +walletpassphrasechange "oldpassphrase" "newpassphrase" +walletprocesspsbt "psbt" ( sign "sighashtype" bip32derivs ) + +== Zmq == +getzmqnotifications +``` +Você também pode digitar `bitcoin-cli help [command]` para obter informações ainda mais detalhadas sobre aquele comando. Por exemplo: +``` +$ bitcoin-cli help getmininginfo +... +Returns a json object containing mining-related information. +Result: +{ (json object) + "blocks" : n, (numeric) The current block + "currentblockweight" : n, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled) + "currentblocktx" : n, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled) + "difficulty" : n, (numeric) The current difficulty + "networkhashps" : n, (numeric) The network hashes per second + "pooledtx" : n, (numeric) The size of the mempool + "chain" : "str", (string) current network name (main, test, regtest) + "warnings" : "str" (string) any network and blockchain warnings +} + +Examples: +> bitcoin-cli getmininginfo +> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ +``` +> :book: ***What is RPC?*** `bitcoin-cli` is just a handy interface that lets you send commands to the `bitcoind`. More specifically, it's an interface that lets you send RPC (or Remote Procedure Protocol) commands to the `bitcoind`. Often, the `bitcoin-cli` command and the RPC command have identical names and interfaces, but some `bitcoin-cli` commands instead provide shortcuts for more complex RPC requests. Generally, the `bitcoin-cli` interface is much cleaner and simpler than trying to send RPC commands by hand, using `curl` or some other method. However, it also has limitations as to what you can ultimately do. + +## Opcional: Conheça as informações do seu node Bitcoin + +Uma variedade de comandos bitcoin-cli podem fornecer informações adicionais sobre seus node Bitcoin. Os mais gerais são: + +`bitcoin-cli -getinfo` retorna informações diferentes do RPC + +```diff +$ bitcoin-cli -getinfo + +! Chain: test +Blocks: 1977694 +Headers: 1977694 +Verification progress: 0.9999993275374796 +Difficulty: 1 + ++ Network: in 0, out 8, total 8 +Version: 219900 +Time offset (s): 0 +Proxy: N/A +Min tx relay fee rate (BTC/kvB): 0.00001000 + +@@ Wallet: ""@@ +Keypool size: 1000 +Unlocked until: 0 +Transaction fee rate (-paytxfee) (BTC/kvB): 0.00000000 + +# Balance: 0.02853102 + +- Warnings: unknown new rules activated (versionbit 28) + +``` + +Outros comandos para obter informações sobre blockchain, mineração, rede, carteira etc. + +``` +$ bitcoin-cli getblockchaininfo +$ bitcoin-cli getmininginfo +$ bitcoin-cli getnetworkinfo +$ bitcoin-cli getnettotals +$ bitcoin-cli getwalletinfo +``` +Por exemplo, `bitcoin-cli getnetworkinfo` fornece uma variedade de informações sobre sua configuração e seu acesso a outras redes: +``` +$ bitcoin-cli getnetworkinfo +{ + "version": 200000, + "subversion": "/Satoshi:0.20.0/", + "protocolversion": 70015, + "localservices": "0000000000000408", + "localservicesnames": [ + "WITNESS", + "NETWORK_LIMITED" + ], + "localrelay": true, + "timeoffset": 0, + "networkactive": true, + "connections": 10, + "networks": [ + { + "name": "ipv4", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "ipv6", + "limited": false, + "reachable": true, + "proxy": "", + "proxy_randomize_credentials": false + }, + { + "name": "onion", + "limited": false, + "reachable": true, + "proxy": "127.0.0.1:9050", + "proxy_randomize_credentials": true + } + ], + "relayfee": 0.00001000, + "incrementalfee": 0.00001000, + "localaddresses": [ + { + "address": "45.79.111.171", + "port": 18333, + "score": 1 + }, + { + "address": "2600:3c01::f03c:92ff:fecc:fdb7", + "port": 18333, + "score": 1 + }, + { + "address": "4wrr3ktm6gl4sojx.onion", + "port": 18333, + "score": 4 + } + ], + "warnings": "Warning: unknown new rules activated (versionbit 28)" +} +``` + +Sinta-se à vontade para consultar qualquer um deles e usar `bitcoin-cli help` se quiser mais informações sobre o que qualquer um deles faz. + +## Resumo: Conhecendo a configuração do seu node Bitcoin + +O diretório `~ /.bitcoin` contém todos os seus arquivos, enquanto `bitcoin-cli help` te retorna uma variedade de comandos, info podem ser usados para obter mais informações sobre como sua configuração e o Bitcoin funcionam. + +## Mas o que vem a seguir? + +Continue "Compreendendo sua configuração do seu node Bitcoin" com [3.3: Setting Up Your Wallet](03_3_Setting_Up_Your_Wallet.md). \ No newline at end of file diff --git a/pt/03_3_Setting_Up_Your_Wallet.md b/pt/03_3_Setting_Up_Your_Wallet.md new file mode 100644 index 0000000..1434ecb --- /dev/null +++ b/pt/03_3_Setting_Up_Your_Wallet.md @@ -0,0 +1,131 @@ +# 3.3: Configurando sua carteira + +Agora você está pronto para começar a trabalhar com Bitcoin. Para começar, você precisará criar um endereço para receber fundos. + +## Crie um endereço + +A primeira coisa que você precisa fazer é criar um endereço para recebimento de pagamentos. Isso é feito com o comando `bitcoin-cli getnewaddress`. Lembre-se que se você quiser mais informações sobre este comando, deve digitar `bitcoin-cli help getnewaddress`. Atualmente, existem três tipos de endereços: `legacy` e os dois tipos de endereço SegWit,` p2sh-segwit` e `bech32`. Se você não especificar de outra forma, você obterá o padrão, que atualmente é `bech32`. + +No entanto, para as próximas seções, em vez disso, usaremos endereços `legacy`, tanto porque `bitcoin-cli` teve alguns problemas iniciais com suas versões anteriores de endereços SegWit, e porque outras pessoas podem não ser capazes de enviar para endereços `bech32`. É improvável que tudo isso seja um problema para você agora, mas no momento queremos começar com exemplos de transações que (na maioria) têm garantia de funcionamento. + +Você pode exigir o endereço `legacy` como segundo argumento para `getnewaddress` ou com o argumento denominado `addresstype`. + +``` +$ bitcoin-cli getnewaddress -addresstype legacy +moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B +``` + +Observe que este endereço começa com um "m" (ou às vezes um "n") para significar um endereço legacy testnet. Seria um "2" para um endereço P2SH ou um "tb1" para um endereço Bech32. + +> :link: **TESTNET vs MAINNET:** O endereço mainnet equivalente começaria com "1" (para Legacy), "3" (para P2SH) ou "bc1" (para Bech32). + +Anote cuidadosamente o endereço. Você precisará entregá-lo a quem enviará os fundos. + +> :book: ***O que é um endereço Bitcoin?*** Um endereço Bitcoin é literalmente onde você recebe dinheiro. É como um endereço de e-mail, mas para fundos. Tecnicamente, é uma chave pública. No entanto, ao contrário de um endereço de e-mail, um endereço de Bitcoin deve ser considerado de uso único: use-o para receber fundos apenas _uma vez_. Quando você quiser receber fundos de outra pessoa ou em algum outro momento, gere um novo endereço. Isso é sugerido em grande parte para melhorar sua privacidade. Todo o blockchain é imutável, o que significa que os exploradores podem observar longas cadeias de transações ao longo do tempo, tornando possível determinar estatisticamente quem é você e quem são seus contatos, não importa o quão cuidadoso você seja. No entanto, se você continuar reutilizando o mesmo endereço, isso se tornará ainda mais fácil. + +> :book: ***O que é uma carteira Bitcoin?*** Ao criar seu primeiro endereço Bitcoin, você também começou a preencher sua carteira Bitcoin. Mais precisamente, você começou a preencher o arquivo `wallet.dat` em seu diretório `~/.bitcoin/testnet3/wallets`. O arquivo `wallet.dat` contém dados sobre preferências e transações, mas mais importante, contém todos os pares de chaves que você criou: a chave pública (que é a fonte do endereço onde você recebe fundos) e a chave privada (que é como você gasta esses fundos). Na maior parte, você não terá que se preocupar com a chave privada: `bitcoind` irá usá-la quando for necessário. No entanto, isso torna o arquivo `wallet.dat` extremamente importante: se você o perder, perderá suas chaves privadas e, se perder suas chaves privadas, perderá seus fundos! + +Com um único endereço em mãos, você pode pular direto para a próxima seção e começar a receber fundos. No entanto, antes de chegarmos lá, vamos discutir brevemente os outros tipos de endereços que você encontrará no futuro e falar sobre alguns outros comandos de carteira que você pode querer usar no futuro. + +### Conhecendo seus endereços de Bitcoin + +Existem três tipos de endereços Bitcoin que você pode criar com o comando RPC `getnewaddress`. Você usará um endereço `legacy` (P2PKH) aqui, enquanto se moverá para um endereço SegWit (P2SH-SegWit) ou Bech32 em [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md). + +Conforme observado acima, a base de um endereço de Bitcoin é uma chave pública: alguém envia fundos para sua chave pública e você usa sua chave privada para resgatá-la. Fácil? Exceto que colocar sua chave pública lá não é totalmente seguro. No momento, se alguém tiver sua chave pública, não poderá recuperar sua chave privada (e, portanto, seus fundos); essa é a base da criptografia, que usa uma função de trapdoor para garantir que você só possa passar da chave privada para a pública, e não vice-versa. Mas o problema é que não sabemos o que o futuro pode trazer. Exceto que sabemos que os sistemas de criptografia eventualmente são quebrados pelo avanço implacável da tecnologia, então é melhor não colocar chaves públicas brutas na rede, para preparar suas transações para o futuro. + +As transações clássicas de Bitcoin criaram endereços P2PKH que adicionaram uma etapa criptográfica adicional para proteger as chaves públicas. + +> :book: ***O que é um endereço legacy (P2PKH)?*** Este é um endereço legado do tipo usado pela antiga rede Bitcoin. Iremos usá-lo em exemplos nas próximas seções. É chamado de endereço Pay to PubKey Hash (ou P2PKH) porque o endereço é um hash de 160 bits de uma chave pública. Usar um hash de sua chave pública como seu endereço cria um processo de duas etapas onde gastar os fundos você precisa revelar a chave privada e a chave pública, e aumenta a segurança futura de acordo. Esse tipo de endereço continua sendo importante para receber fundos de pessoas com software de carteira desatualizado. + +Conforme descrito mais detalhadamente em [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md), a Block-Size Wars do final dos anos 10 do Bitcoin resultaram em um novo tipo de endereço: SegWit. Este é o tipo de endereço preferido atualmente e deve estar totalmente integrado ao Bitcoin-Core neste exato momento. + +SegWit significa simplesmente "testemunha segregada" e é uma maneira de separar as assinaturas da transação do resto da transação para reduzir o tamanho da transação. Alguns endereços SegWit entrarão em alguns de nossos exemplos anteriores a 4.6 como endereços de troco, que você verá como endereços que começam com "tb". Isso é bom porque o `bitcoin-cli` suporta inteiramente seu uso. + +Existem dois endereços desse tipo: + +> :book: ***O que é um endereço P2SH-SegWit (também conhecido como Nested SegWit)?*** Esta é a primeira geração do SegWit. Ele envolve o endereço SegWit em um hash de script para garantir a compatibilidade com versões anteriores. O resultado cria transações que são cerca de 25% + menores (com reduções correspondentes nas taxas de transação). + +> :book: ***O que é um endereço Bech32 (também conhecido como SegWit nativo, também conhecido como P2WPKH)?*** Esta é a segunda geração do SegWit. Está totalmente descrito em [BIP 173] (https://en.bitcoin.it/wiki/BIP_0173). Ele cria transações que são ainda menores, mas mais notavelmente também tem algumas vantagens na criação de endereços que são menos propensos a erro humano e têm alguma correção de erro implícita além disso. Ele * não * é compatível com versões anteriores como o P2SH-SegWit era e, portanto, algumas pessoas podem não ser capazes de enviar para ele. + +Existem outros tipos de endereços de Bitcoin, como P2PK (que paga a uma chave pública simples e está obsoleto devido à sua insegurança futura) e P2SH (que paga a um Hash de script e que é usado pelo SegWit e esta aninhado com a primeira geração endereços; vamos conhecê-lo mais detalhadamente em alguns capítulos). + +## Opcional: assine uma mensagem + +Às vezes, você precisará provar que controla um endereço Bitcoin (ou melhor, que controla sua chave privada). Isso é importante porque permite que as pessoas saibam que estão enviando fundos para a pessoa certa. Isso pode ser feito criando uma assinatura com o comando `bitcoin-cli signmessage`, na forma `bitcoin-cli signmessage [endereço] [mensagem]`. Por exemplo: + +``` +$ bitcoin-cli signmessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "Hello, World" +HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI= +``` +Você receberá a assinatura como um retorno. + +> :book: ***What is a signature?*** A digital signature is a combination of a message and a private key that can then be unlocked with a public key. Since there's a one-to-one correspendence between the elements of a keypair, unlocking with a public key proves that the signer controlled the corresponding private key. + +Another person can then use the `bitcoin-cli verifymessage` command to verify the signature. He inputs the address in question, the signature, and the message: +``` +$ bitcoin-cli verifymessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" +true +``` +Se todos eles corresponderem, a outra pessoa saberá que pode transferir fundos com segurança para a pessoa que assinou a mensagem enviando para o endereço. + +Se algum golpista estivesse criando assinaturas, isso produziria um invalido. +``` +$ bitcoin-cli verifymessage "FAKEV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" +error code: -3 +error message: +Invalid address +``` + +## Opcional: descarregar sua carteira + +Pode parecer perigoso ter todas as suas chaves privadas insubstituíveis em um único arquivo. É para isso que serve `bitcoin-cli dumpwallet`. Ele permite que você faça uma cópia de seu wallet.dat: +``` +$ bitcoin-cli dumpwallet ~/mywallet.txt +``` +O arquivo `mywallet.txt` em seu diretório home terá uma longa lista de chaves privadas, endereços e outras informações. Lembre-se, você não gostaria de colocar esses dados em um arquivo de texto simples, em uma configuração com fundos reais! + +Você pode então recuperá-lo com `bitcoin-cli importwallet`. +``` +$ bitcoin-cli importwallet ~/mywallet.txt +``` +Mas observe que isso requer um node não prunado. +``` +$ bitcoin-cli importwallet ~/mywallet.txt +error code: -4 +error message: +Importing wallets is disabled when blocks are pruned +``` + +## Opcional: Visualize suas chaves privadas + +Às vezes, você pode querer realmente olhar para as chaves privadas associadas aos seus endereços Bitcoin. Talvez você queira assinar uma mensagem ou gastar bitcoins em uma máquina diferente. Talvez você só queira fazer backup de algumas chaves privadas importantes. Você também pode fazer isso com seu arquivo de descarregado, já que ele pode ser lido por humanos. +``` +$ bitcoin-cli dumpwallet ~/mywallet.txt +{ + "filename": "/home/standup/mywallet.txt" +} +``` +Mais provavelmente, você deseja apenas examinar a chave privada associada a um endereço específico. Isso pode ser feito com o comando `bitcoin-cli dumpprivkey`. +``` +$ bitcoin-cli dumpprivkey "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" +cTv75T4B3NsG92tdSxSfzhuaGrzrmc1rJjLKscoQZXqNRs5tpYhH +``` +Você pode salvar essa chave em um local seguro, de preferência em algum lugar sem conexão com a Internet. + +Você também pode importar qualquer chave privada, de um despejo de carteira ou um despejo de chave individual, da seguinte maneira: +``` +$ bitcoin-cli importprivkey cW4s4MdW7BkUmqiKgYzSJdmvnzq8QDrf6gszPMC7eLmfcdoRHtHh +``` +Novamente, espere que isso exija um node não prunado. Espere que isso demore um pouco, já que o `bitcoind` precisa reler todas as transações anteriores, para ver se há alguma nova. + +> :information_source: **NOTA:** Muitas carteiras modernas preferem [códigos mnemônicos](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) para gerar as sementes necessárias para criar as chaves privadas. Esta metodologia não é usada `bitcoin-cli`, então você não será capaz de gerar listas de palavras úteis para lembrar suas chaves privadas. + +_Você digitou aquele endereço Bitcoin que gerou, enquanto assinava uma mensagens e agora esta descarregando as chaves. Se você acha que é muito complicado, concordamos. Também está sujeito a erros, um tópico que abordaremos na próxima seção._ + +## Resumo: Configurando sua carteira + +Você precisa criar um endereço para receber fundos. Seu endereço é armazenado em uma carteira, da qual você pode fazer backup. Você também pode fazer muito mais com um endereço, como descartar sua chave privada ou usá-la para assinar mensagens. Mas, realmente, criar esse endereço é _tudo_ que você precisa fazer para receber os fundos. + +## Mas oque vem a seguir? + +Um passo para trás em "Compreendendo a configuração do seu node Bitcoin" com [Usando variáveis de linha de comandos](03_3__Interlude_Using_Command-Line_Variables.md). \ No newline at end of file diff --git a/pt/03_3__Interlude_Using_Command-Line_Variables.md b/pt/03_3__Interlude_Using_Command-Line_Variables.md new file mode 100644 index 0000000..0c74363 --- /dev/null +++ b/pt/03_3__Interlude_Using_Command-Line_Variables.md @@ -0,0 +1,40 @@ +# Usando variáveis de linha de comando + +A seção anterior demonstrou vários comandos de linha de comando usados sem ofuscação ou interferência. No entanto, geralmente essa não é a melhor maneira de executar Bitcoin na linha de comando. Como você está lidando com variáveis longas, complexas e ilegíveis, é fácil cometer um erro se você estiver copiando essas variáveis (ou, satoshi forfend, se você as estiver digitando manualmente). Como essas variáveis podem significar a diferença entre receber e perder dinheiro real, você não _quer_ cometer erros. Por esses motivos, sugerimos enfaticamente o uso de variáveis de linha de comando para salvar endereços, assinaturas ou outras cadeias de informações longas sempre que for razoável. + +Se estiver usando `bash`, você pode salvar as informações em uma variável como esta: +``` +$ VARIABLE=$(command) +``` + +Esta é uma substituição de comando simples, o equivalente a `VARIABLE = command`. O comando entre parênteses é executado e, em seguida, atribuído à VARIÁVEL. + +Para criar um novo endereço, seria assim: +``` +$ unset NEW_ADDRESS_1 +$ NEW_ADDRESS_1=$(bitcoin-cli getnewaddress "" legacy) +``` +Esses comandos limpam a variável NEW_ADDRESS_1, apenas para ter certeza, e então a preenchem com os resultados do comando `bitcoin-cli getnewaddress`. + +Você pode então usar o comando `echo` do seu shell para ver o seu (novo) endereço: +``` +$ echo $NEW_ADDRESS_1 +mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE +``` +Como seu endereço está em uma variável, agora você pode assinar facilmente uma mensagem para esse endereço, sem se preocupar em digitar o endereço incorretamente. É claro que você também salvará essa assinatura em uma variável! +``` +$ NEW_SIG_1=$(bitcoin-cli signmessage $NEW_ADDRESS_1 "Hello, World") +$ echo $NEW_SIG_1 +IPYIzgj+Rg4bxDwCyoPiFiNNcxWHYxgVcklhmN8aB2XRRJqV731Xu9XkfZ6oxj+QGCRmTe80X81EpXtmGUpXOM4= +``` +O restante deste tutorial usará esse estilo de armazenar informações em variáveis quando for prático. + +> :book: ***Quando não é prático usar variáveis de linha de comando?*** Variáveis de linha de comando não são práticas se você precisar usar as informações em algum lugar diferente da linha de comando. Por exemplo, salvar sua assinatura pode não ser útil se você apenas tiver que enviá-la a outra pessoa por e-mail. Além disso, alguns comandos futuros produzirão objetos JSON em vez de informações simples, e as variáveis não podem ser usadas para capturar essas informações ... pelo menos não sem um _pouco_ de mais trabalho. + +## Resumo: Usando variáveis de linha de comando + +Variáveis de shell podem ser usadas para manter longas strings, minimizando as chances de erros. + +## Mas o que vem a seguir? + +Continue "Compreendendo a configuração do seu node Bitcoin" com [3.4: Recebendo uma transação](03_4_Receiving_a_Transaction.md). \ No newline at end of file From cde0e237c3477b7d8b5eac49b10ccadebcc48e21 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 11:30:51 -0300 Subject: [PATCH 27/50] Chapter 15 Translated Translation : Finished Revision : Needed --- pt/04_0_Sending_Bitcoin_Transactions.md | 29 ++ pt/04_1_Sending_Coins_The_Easy_Way.md | 102 +++++ pt/04_2_Creating_a_Raw_Transaction.md | 274 +++++++++++ pt/04_2__Interlude_Using_JQ.md | 429 ++++++++++++++++++ ..._a_Raw_Transaction_with_Named_Arguments.md | 97 ++++ ..._4_Sending_Coins_with_a_Raw_Transaction.md | 187 ++++++++ pt/04_4__Interlude_Using_Curl.md | 314 +++++++++++++ ...g_Coins_with_Automated_Raw_Transactions.md | 171 +++++++ pt/04_6_Creating_a_Segwit_Transaction.md | 288 ++++++++++++ 9 files changed, 1891 insertions(+) create mode 100644 pt/04_0_Sending_Bitcoin_Transactions.md create mode 100644 pt/04_1_Sending_Coins_The_Easy_Way.md create mode 100644 pt/04_2_Creating_a_Raw_Transaction.md create mode 100644 pt/04_2__Interlude_Using_JQ.md create mode 100644 pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md create mode 100644 pt/04_4_Sending_Coins_with_a_Raw_Transaction.md create mode 100644 pt/04_4__Interlude_Using_Curl.md create mode 100644 pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md create mode 100644 pt/04_6_Creating_a_Segwit_Transaction.md diff --git a/pt/04_0_Sending_Bitcoin_Transactions.md b/pt/04_0_Sending_Bitcoin_Transactions.md new file mode 100644 index 0000000..f906763 --- /dev/null +++ b/pt/04_0_Sending_Bitcoin_Transactions.md @@ -0,0 +1,29 @@ +# Capítulo 4: Enviando transações no Bitcoin + +Este capítulo descreve três métodos diferentes para enviar bitcoins para endereços P2PKH normais à partir da linha de comando, usando apenas o ```bitcoin-cli```. + +## Objetivos deste capítulo + +Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: + + * Decidir como enviar dinheiro usando o Bitcoin; + * Criar uma transação bruta; + * Usar a aritmética para calcular as taxas. + +Os objetivos secundários incluem a capacidade de: + + * Compreender transações e taxas de transação; + * Entender as transações ```legacy``` e ```SegWit```; + * Usar métodos básicos para enviar dinheiro; + * Usar métodos de cálculo de taxa automática para enviar dinheiro; + * Entender os perigos de transações brutas. + +## Tabela de Conteúdo + + * [Seção 1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md) + * [Seção 2: Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md) + * [Prefácio: Usando o JQ](04_2__Interlude_Using_JQ.md) + * [Seção 3: Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) + * [Seção 4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) + * [Seção 5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) + * [Seção 6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md) \ No newline at end of file diff --git a/pt/04_1_Sending_Coins_The_Easy_Way.md b/pt/04_1_Sending_Coins_The_Easy_Way.md new file mode 100644 index 0000000..6131040 --- /dev/null +++ b/pt/04_1_Sending_Coins_The_Easy_Way.md @@ -0,0 +1,102 @@ +# 4.1: Enviando bitcoins no modo easy + +O ```bitcoin-cli``` oferece três principais maneiras de enviar bitcoins: Utilizando um simples comando; Utilizando uma transação bruta e; Utilizando uma transação bruta com cálculos. Cada um possui seus prós e contras. Este primeiro método de envio será o mais simples. + +## Definindo sua taxa de transação + +Antes de enviar qualquer bitcoin pela rede, devemos pensar sobre as taxas de transação que iremos pagar. + +> :book: ***O que é uma taxa de transação?*** Não existe almoço grátis. Os mineradores adicionam as transações nos blocos porque são pagos para fazer isso. Eles não apenas são pagos pela rede para criar o bloco, mas também são pagos pelas pessoas que realizam as transações para incluí-las na blockchain. Se não pagarmos a taxa, nossa transação pode ficar travada... Para sempre (ou, até que seja salva por alguns dos truques que falaremos no [capítulo cinco](05_0_Controlling_Bitcoin_Transactions.md)). + +Ao usar métodos simples e automatizados para criar transações, conforme descrito aqui e na sessão [§4.5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o Bitcoin calculará as taxas de transação para nós. Isso é feito usando taxas flutuantes, onde o ```bitcoind``` observa quanto tempo as transações estão demorando para confirmar e calcula automaticamente o que devemos gastar. + +Podemos ter um controle dessas informações colocando os valores racionais no nosso arquivo ```~/.bitcoin/bitcoin.conf```. Os valores de baixo custo a seguir garantiriam que houvesse uma taxa de transação mínima de 10.000 satoshis por kByte de dados em nossa transação e solicitariam que as taxas flutuantes calculassem uma boa quantia para colocar a nossa transação nos próximos seis blocos. +``` +mintxfee=0.0001 +txconfirmtarget=6 +``` +No entanto, como iremos partir do pressuposto que ninguém que esteja fazendo este tutorial queira esperar para as transações serem confirmadas, vamos adotar os seguintes valores: +``` +mintxfee=0.001 +txconfirmtarget=1 +``` +Devemos inseri-los no arquivo ```~/.bitcoin/bitcoin.conf```, na seção principal, no início do arquivo ou se quisermos ter a certeza de nunca iremos utilizá-lo em outro lugar, podemos colocar na sessão ```[test]```. + +Para trabalharmos neste tutorial, estamos dispostos a gastar 100.000 satoshis por kB em cada transação, e queremos colocar cada transação no próximo bloco! Para colocar isso em uma perspectiva para melhor entendimento, uma transação simples é executada com um tamanho de 0,25 KB a 1 KB, então estaremos pagando algo em torno de 25 mil a 100 mil satoshis, sendo que atualmente, taxas acima de 10 mil são consideradas altíssimas para transações de quantidade média. + +Depois de editar o arquivo ```bitcoin.conf```, vamos reiniciar o bitcoind usando dois comandos: +``` +$ bitcoin-cli stop +$ bitcoind -daemon +``` + +## Obtendo um endereço + +Precisamos encontrar algum endereço para enviar nossas moedas. Normalmente, alguém nos envia em um endereço e talvez nos dê uma assinatura para provar que é o proprietário desse endereço. Como alternativa, podemos nos fornecer um QR code para que possamos digitalizar, evitando assim possíveis erros de digitação na hora de colocar o endereço no local do destinatário. Em nosso caso, vamos enviar os bitcoins para `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, que é o endereço de retorno de um antigo fauce da rede Testenet. + +> :book: ***O que é um QR code?*** Um QR code é apenas um jeito diferente de passar o endereço Bitcoin. Muitas carteiras geram os QR codes para nós, enquanto alguns sites tentam convertê-los em um endereço usando o QR code. Obviamente, só podemos aceitar um QR code de um site no qual confiamos. Um pagador pode usar um leitor de código de barras para ler o código QR e, em seguida, pagá-lo. + +## Enviando os bitcoins + +Agora estamos prontos para enviar alguns bitcoins. Na verdade, isso é bastante simples por meio da linha de comando. Basta usar ```bitcoin-cli sendtoaddress [endereço] [quantidade]```. Portanto, para enviar uns satoshinhos para o endereço `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, basta fazer o seguinte: +``` +$ txid=$(bitcoin-cli sendtoaddress n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi 0.001) +$ echo $txid +93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8 +``` + +> 🙏 Para ajudar a manter os faucets da rede de testes vivos, tente usar o endereço que nos foi enviado os bitcoins no capítulo anterior, onde falamos sobre os recebimentos de transações. + +Precisamos nos certificar de que o endereço digitado é o lugar para onde desejamos enviá-lo. Por isso, certifique-se _duas vezes_. Se cometermos algum erro no Bitcoin, não há como voltar atrás. + +Iremos receber um txid de retorno quando usarmos este comando. + +> ❕ Você pode acabar com um código de erro se não tivermos bitcoins suficientes na carteira para fazer a transação. Dependendo do nosso saldo atual, que podemos acessar usando o ```bitcoin-cli getbalance```, pode ser necessário ajustar o valor que iremos enviar para que bata com o valor que está sendo enviado, não se esquecendo da taxa de transação no meio deste processo. Se o nosso saldo atual for 0,001, podemos tentar enviar 0,0001. Como alternativa, seria melhor tirar a taxa que esperamos pagar que foi enviada na mensagem de erro do nosso saldo atual. Esta é uma boa prática, pois muitas carteiras esperam que calculemos nosso próprio valor + taxas ao fazermos as transações, mesmo as carteiras mais populares usam essa premissa. + +> :warning: **ATENÇÃO:** O comando ```bitcoin-cli``` realmente gera comandos usando o JSON-RPC quando está se comunicando com o bitcoind. Eles podem ser muito exigentes. Este é um exemplo: Se listarmos a quantidade de bitcoin sem o zero à esquerda (ou seja usando ".1" em vez de "0.1"), o ```bitcoin-cli``` irá acusar um erro com uma mensagem misteriosa. + +> :warning: **ATENÇÃO:** Mesmo se formos cuidadosos com nossos dados, é possível que haja este erro: _"Fee estimation failed. Fallbackfee is disabled"_. De maneira geral, isso significa que nosso ```bitcoind``` local não tem informações suficientes para estimar as taxas. Não é para vermos isso se estivermos esperado que nossa blockchain sincronize e configure nosso sistema com o Bitcoin Standup. Mas se não estivermos totalmente sincronizados, podemos nos deparar com este erro. Também pode ser que não estejamos usando um ```bitcoin.conf``` padrão: A informação ```blocksonly = 1``` fará com que nosso ```bitcoind``` não consiga estimar as taxas. + +## Examinando nossa transação + +Podemos ver nossa transação usando o ID de transação: +``` +{ + "amount": -0.00100000, + "fee": -0.00022200, + "confirmations": 0, + "trusted": true, + "txid": "93250d0cacb0361b8e21030ac65bc4c2159a53de1075425d800b2d7a8ab13ba8", + "walletconflicts": [ + ], + "time": 1592604194, + "timereceived": 1592604194, + "bip125-replaceable": "no", + "details": [ + { + "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", + "category": "send", + "amount": -0.00100000, + "vout": 1, + "fee": -0.00022200, + "abandoned": false + } + ], + "hex": "0200000001e982921bb0189afc486e20bb05cc5825c71a0ba8868043ed04ece9ab0cb12a8e010000006a47304402200fc493a01c5c9d9574f7c321cee6880f7f1df847be71039e2d996f7f75c17b3d02203057f5baa48745ba7ab5f1d4eed11585bd8beab838b1ca03a4138516fe52b3b8012102fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9bafeffffff02e8640d0000000000160014d37b6ae4a917bcc873f6395741155f565e2dc7c4a0860100000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac780b1b00" +} +``` +Você pode ver não apenas o valor transferido (0,001 BTC), mas também uma taxa de transação (0,000222 BTC), que é cerca de um quarto da taxa mínima de 0,001 BTC/kB que foi definida, o que sugere que a transação foi de cerca de um quarto de kB de tamanho. + +Enquanto esperamos que ela seja confirmada, podemos notar que o ```bitcoin-cli getbalance``` mostra que nosso dinheiro já foi debitado. Da mesma forma, o ```bitcoin-cli listunspent``` mostrará que uma transação inteira foi perdida, mesmo que fosse mais do que o que queríamos enviar. Há uma razão para isso: Sempre que temos moedas entrando, precisamos enviar _tudo_ junto, e temos que fazer um pouco de malabarismos se quisermos realmente ficar com parte dele! Mais uma vez, o ```sendtoaddress``` cuida de tudo isso para nós, o que significa que não precisamos nos preocupar em fazer qualquer alteração até enviar uma transação bruta. Nesse caso, uma nova transação aparecerá com nossa alteração quando nosso envio for incorporado a um bloco. + +## Resumo do Enviando bitcoins no modo easy + +Para enviar moedas facilmente, precisamos nos certificar de que nossos padrões de transação sejam racionais, obtendo um endereço e enviando as nossas moedas para lá. É por isso que esse modo é o mais fácil deles! + +> :fire: ***Qual é o poder de enviar moedas no modo easy?*** +> _As vantagens._ É fácil. Não precisamos nos preocupar com coisas misteriosas como UTXOs. Não precisamos calcular as taxas de transação manualmente, então, é provável que não iremos cometer erros que custem grandes valores Se o nosso único objetivo é sentar na frente do computador e enviar alguns bitcoins, este é o caminho certo para fazer isso. +> _As desvantagens._ É alto nível. Temos muito pouco controle sobre o que está acontecendo e não podemos fazer nada demais. Se estamos planejando desenvolver um software mais complexo utilizando o Bitcoin ou se desejamos um entendimento mais profundo de como o Bitcoin funciona, então o modo easy é apenas um carrossel sem graça antes de chegarmos nas montanhas russas. + +## O Que Vem Depois? + +Vamos continuar "Enviando Transações de Bitcoin" na sessão [§4.2 Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md). \ No newline at end of file diff --git a/pt/04_2_Creating_a_Raw_Transaction.md b/pt/04_2_Creating_a_Raw_Transaction.md new file mode 100644 index 0000000..4a5f0b6 --- /dev/null +++ b/pt/04_2_Creating_a_Raw_Transaction.md @@ -0,0 +1,274 @@ +# 4.2 Criando uma transação bruta + +Agora estamos pronto para criar transações brutas no Bitcoin. Isso permite que enviemos dinheiro, mas criemos as transações com a precisão desejada. Nesta primeira seção, iremos nos concentrar em uma transação simples de uma entrada e uma saída. Este tipo de transação _não_ é realmente útil, porque raramente vamos querer enviar todo o nosso dinheiro para uma pessoa (a menos que estejamos apenas encaminhando, como se estivesse movendo coisas de uma carteira para outra). Portanto, esse _não é o melhor método_ para enviar dinheiro. É apenas um conteúdo fundamental para _realmente_ enviar dinheiro com uma transação bruta. + +## Compreendendo a transação no Bitcoin + +Antes de mergulhar na criação de transações brutas, devemos nos certificar de que entendemos como uma transação no Bitcoin funciona. Tudo gira entorno dos UTXOs. + +> :book: ***O que é um UTXO?*** Quando recebemos dinheiro em nossa carteira Bitcoin, ele aparece como uma transação individual. Cada uma dessas transações é chamada de saída de transação não gasta (Unspent Transaction Output em inglês, mais conhecida como UTXO). Não importa se vários pagamentos foram feitos para o mesmo endereço ou para vários endereços: Cada transação recebida permanece distinta na carteira como um UTXO. + +Ao criarmos uma nova transação de saída, reunimos um ou mais UTXOs, cada um representando um pouquinho do dinheiro que recebemos. Nós os usamos como entradas para uma nova transação. Juntos, o valor deles deve ser igual ao que desejamos gastar _ou mais do que o total_. Em seguida, geramos uma ou mais saídas, que dão o dinheiro representado pelas entradas a uma ou mais pessoas. Isso cria novos UTXOs para os destinatários, que podem então usá-los para financiar transações futuras. + +Aqui está o truque: _Todos os UTXOs que coletarmos são gastos na íntegra!_ Isso significa que se quisermos enviar apenas parte do dinheiro em um UTXO para outra pessoa, também precisamos gerar uma saída adicional que envia o resto para nós! Por enquanto, não vamos nos preocupar com isso, mas o uso de um endereço de mudança será vital ao passar da teoria deste capítulo para transações mais práticas. + +## Listando as transações não gastas + +Para criar uma nova transação bruta, devemos saber quais UTXOs estão disponíveis para gastar. Podemos determinar essas informações com o comando ```bitcoin-cli listunspent```: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 20, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + }, + { + "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", + "vout": 1, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00050000, + "confirmations": 3, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 3, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] + +``` +Esta lista mostra três UTXOs diferentes, no valor de 0,0001, 0,0005 e 0,00022 BTC. Observe que cada um tem o próprio _txid_ distinto e permanece seperado na carteira, até mesmo os dois últimos, que foram enviados para o mesmo endereço. + +Quando quisermos gastar um UTXO, não é suficiente apenas saber o id da transação. Isso porque cada transação pode ter várias saídas! Lembra daquele primeiro valor que o faucet nos enviou? Na transação, parte do dinheiro foi para nós e parte para outra pessoa. O ```txid``` se refere à transação geral, enquanto um ```vout``` diz qual das múltiplas saídas recebemos. Nesta lista, cada uma dessas transações é a primeira ```vout``` de uma transação anterior, mas _não necessariamente é sempre o caso_. + +Portanto, o txid+vout=UTXO. Essa será a base de qualquer transação bruta. + +## Escrevendo uma transação bruta com uma saída + +You're now ready to write a simple, example raw transaction that shows how to send the entirety of a UTXO to another party. As noted, this is not necessarily a very realistic real-world case. +Agora estamos prontos para escrever um exemplo simples de transação bruta que mostra como enviar um UTXO inteiro para outra parte. Conforme falamos anteriormente, este não é um caso muito realista. + +> :warning: **Atenção:** É muito fácil perder dinheiro com uma transação bruta. Considere que todas as instruções sobre como enviar bitcoins por meio de transações brutas são _muito_, _muito_ perigosas. Sempre que estiver enviando moedas na _mainnet_ para outras pessoas, devemos usar um dos outros métodos explicados neste capítulo. Criar transações brutas é extremamente útil se estivermos escrevendo programas para o bitcoin, mas _só_ neste caso. Por exemplo: Ao escrever este exemplo para uma versão anterior deste tutorial, acidentalmente gastamos a transação errada, embora tivessemos cerca de 10 vezes mais. Quase tudo isso foi enviado para os mineradores. + +### Preparando a transação bruta + +Para as melhores práticas, iremos começar cada transação registrando cuidadosamente os txids e vouts que iremos gastar. + +Nesse caso, vamos gastar um no valor de 0,00050000 BTC porque é o único com um valor decente. +``` +$ utxo_txid="61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a" +$ utxo_vout="1" +``` +Da mesma forma, devemos registrar o endereço do destinatário para ter certeza de que está correto. No nosso exemplo estamos enviando novamente o saldo de volta para o faucet: +``` +$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" +``` +Como de prache, vamos verificar as variáveis com cuidado, para ter certeza de que são aquilo que esperamos! +``` +$ echo $utxo_txid +61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a +$ echo $utxo_vout +1 +$ echo $recipient +n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +``` +Esse destinatário é particularmente importante, porque se bagunçarmos tudo, nosso dinheiro terá dado _tchau tchau_! E como já vimos, escolher a transação errada pode resultar em perda de dinheiro! Portanto, vamos verificar tudo, pelo menos uma vez mais do que a quantidade de costume. + +### Entendendo a taxa de transação + +Cada transação tem uma taxa associada. Ela fica _implícita_ quando enviamos uma transação bruta: O valor que vamos pagar como taxa é sempre igual ao valor de entrada menos o valor de saída. Portanto, temos que diminuir um pouco o valor enviado para ter certeza de que nossa transação será realizada. + +> :warning: **Atenção:** Esta é a parte muito perigosa das transações brutas! Como gastamos automaticamente toda a quantidade de UTXOs que tivermos, é extremamente importante certificar-se de que sabemos: (1) Precisamente quais UTXOs estamos utilizando; (2) Exatamente quanto dinheiro ele possui; (3) Exatamente quanto dinheiro estamos enviando; e (4) qual é a diferença que ficará para os mineradores. Se errarmos e, por exemplo, usarmos o UTXO errado (um que tenha mais dinheiro do que pensávamos) ou se enviarmos muito pouco dinheiro, o excesso será perdido. _Para sempre_! Não podemos cometer esse erro! Por isso, é importante sabermos as entradas e saídas com _precisão_. Ou melhor, não utilizarmos as transações brutas, exceto como parte de um programa cuidadosamente considerado e verificado três vezes. + +> :book: ***Quanto devemos gastar com taxas de transação?*** [Bitcoin Fees](https://bitcoinfees.21.co/) tem uma ótima avaliação ao vivo. O site diz que "fastest and cheapest transaction fee is currently XXX satoshis/byte" onde o XXX será a quantidade de satoshis por byte que precisaremos pagar e também, "For the median transaction size of YYY bytes, this results in a fee of ZZ,ZZZ satoshis", onde YYY é o tamanho de uma transação média e ZZ,ZZZ é o resultado da multiplicação entre YYY e XXX. No caso, precisamos apenas observar o valor ZZ,ZZZ descrito no site. + +No momento em que este tutorial está sendo escrito, o _Bitcoin Fees_ sugere uma taxa de transação de cerca de 10.000 satoshis, que é o mesmo que 0,0001 BTC. Obviamente, isso é para a mainnet, não para a testnet, mas queremos testar as coisas de forma realista, então iremos utilizar esta quantidade. + +Nesse caso, isso vamos pegar 0,0005 BTC no UTXO que selecionamos, reduzindo a quantidade de 0,0001 BTC para a taxa de transação e enviar os 0,0004 BTC restantes. E este é um exemplo do porque os micropagamentos não funcionam na rede principal do Bitcoin, porque uma taxa de transação que consome 20% do valor enviado é muito cara, agora imagina se os valores forem menores do que a taxa de transação. Por isso que temos a Lightning. + +> :warning: **Atenção:** Quanto menor for a taxa de transação, mais tempo irá demorar para que nossa transação entre na blockchain. O site _Bitcoin Fees_ lista os tempos que precisaremos esperar em relação a quantidade de satoshi por byte. Como os blocos são construídos em média a cada 10 minutos, a mudança de taxa pode significar uma mudança de espera de minutos para algumas horas ou dias! Portanto, escolha uma taxa de transação apropriada para o que estamos enviando. É importante observar que nunca devemos colocar taxas abaixo da quantidade mínima para transação, que é 0,0001 BTC. + +### Escrevendo a transação bruta + +Agora estamos prontos para criar a transação bruta. Usaremos o comando ```createrawtransaction```, que pode parecer um pouco intimidante. Isso porque o comando ```createrawtransaction``` não o protege inteiramente do JSON RPC que o ```bitcoin-cli``` utiliza. Ao invés disso, vamos inserir uma matriz JSON para listar os UTXOs que está gastando e um objeto JSON para listar as saídas. + +Este é o formato padrão: +``` +$ bitcoin-cli createrawtransaction +'''[ + { + "txid": "'$your_txid'", + "vout": '$your_vout' + } +]''' +'''{ + "'$your_recipient'": bitcoin_amount + }''' +``` + + Não, não é um erro de digitação. Existem todos os tipos de citações malucas, mas confie que elas farão a coisa certa. Vamos usar `'''` para marcar o início e o fim do array e no objeto JSON. Protegendo as palavras normais como ```"this"```, mas não precisamos proteger os números: ```0```. Se forem variáveis, vamos inserir as aspas simples, como ```"'$this_word'"``` e ```'$this_num'```. (Ufa! Não se preocupe, você pega o jeito). + + Aqui está um comando que cria uma transação bruta para enviar $utxo para o $recipient. +``` +$ rawtxhex=$(bitcoin-cli createrawtransaction '''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' '''{ "'$recipient'": 0.0004 }''') +$ echo $rawtxhex +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f3610100000000ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +``` + +### Verificando a transação bruta + +Depois disso, devemos verificar a transação bruta com o comando ```decoderawtransaction``` para ter certeza de que faremos a coisa certa. +``` +$ bitcoin-cli decoderawtransaction $rawtxhex +{ + "txid": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", + "hash": "dcd2d8f0ec5581b806a1fbe00325e1680c4da67033761b478a26895380cc1298", + "version": 2, + "size": 85, + "vsize": 85, + "weight": 340, + "locktime": 0, + "vin": [ + { + "txid": "61f3b7016bf1ecc3987b8805207e79362e4de8026682e149107999b779426e3a", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00040000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + ] + } + } + ] +} +``` + +É importante verificarmos o ```vin```. Estamos gastando a transação certa? Ela contém a quantia de dinheiro esperada? (Vamos verificar com o comando ```bitcoin-cli gettransaction``` e nos certificar de olhar o ```vout``` se está correto). Além disso, vamos verificar o nosso ```vout```. Estamos enviando a quantidade correta? Está indo para o endereço certo? Finalmente, vamos fazer as contas para ter certeza de que o dinheiro que irá para as taxas está correto. O valor do UTXO menos a quantia que está sendo gasta é igual à taxa da transação esperada? + +> :information_source: **NOTA:** Podemos notar que cada entrada tem um número de sequência, definido aqui como 4294967295, que é 0xFFFFFFFF. Esta é a última fronteira das transações Bitcoin, porque é um campo padrão em transações que foram originalmente planejadas para um propósito específico, mas nunca foram totalmente implementadas. Portanto, agora existe esse inteiro parado em transações que podem ser reaproveitadas para outros usos. E, de fato, tem sido. No momento em que este livro foi escrito, havia três usos diferentes para a variável chamada ```nSequence``` no código Bitcoin Core: Ela habilita a possibilidade de RBF, ```nLockTime``` e timelocks relativos. Se não houver nada de estranho acontecendo, o ```nSequence``` será definido como 4294967295. Ajustar para um valor mais baixo sinaliza que coisas especiais estão acontecendo. + +### Assinando a transação bruta + +Até o momento, nossa transação bruta é apenas uma teoria: _Podemos_ enviá-la, mas nada irá acontecer. Precisamos fazer algumas coisas para colocá-la na rede. + +Primeiro, precisamos assinar nossa transação bruta: +``` + +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex +{ + "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", + "complete": true +} +$ signedtx="02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000" +``` +Observe que capturamos o hexadecimal assinado manualmente, ao invés de tentar analisá-lo a partir do objeto JSON. Um pacote de software chamado "JQ" poderia ter um desempenho melhor, como explicaremos no próximo prefácio. + +### Enviando a transação bruta + +Agora temos uma transação bruta pronta para ser usada, mas nada acontece com ela se não a colocarmos na rede, o que iremos fazer com o comando ```sendrawtransaction```. O retorno dele será uma txid: +``` +$ bitcoin-cli sendrawtransaction $signedtx +a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a +``` +Iremos observar imediatamente que o UTXO e o as nossas moedas foram removidas da nossa carteira: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "address": "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + "label": "", + "scriptPubKey": "76a9141b72503639a13f190bf79acf6d76255d772360b788ac", + "amount": 0.00010000, + "confirmations": 23, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/1']02fd5740996d853ea51a6904cf03257fc11204b0179f344c49739ec5b20b39c9ba)#62rud39c", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 6, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] + +$ bitcoin-cli getbalance +0.00032000 +``` +Logo o ```listtransactions``` deve mostrar uma transação confirmada da categoria 'send'. +``` + { + "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", + "category": "send", + "amount": -0.00040000, + "vout": 0, + "fee": -0.00010000, + "confirmations": 1, + "trusted": true, + "txid": "a1fd550d1de727eccde6108c90d4ffec11ed83691e96e119d842b3f390e2f19a", + "walletconflicts": [ + ], + "time": 1592608574, + "timereceived": 1592608574, + "bip125-replaceable": "no", + "abandoned": false + } +``` +Podemos observar que ele corresponde aos endereços ```txid``` e ```recipient``` (recebedor). Não só mostra o ```amount``` (montante) enviado, mas também mostra a ```fee``` (taxa) da transação. E, a transação já recebeu uma confirmação, porque oferecemos uma taxa que seria colocado no próximo bloco. + +Parabéns! Estamos um pouco mais pobres agora! + +## Resumo do Criando uma transação bruta + +Quando satoshinhos entram na nossa carteira Bitcoin, eles permanecem em quantidades distintas, chamadas de UTXOs. Ao criar uma transação bruta para enviar as moedas, usamos um ou mais UTXOs para financiá-la. Podemos então, criar uma transação bruta, assiná-la e enviá-la pela rede Bitcoin. No entanto, esta é apenas uma base do que realmente acontece: Geralmente precisaremos criar uma transação bruta com várias saídas para realmente enviar algo na rede Bitcoin! + +## O que vem depois? + +Vamos fazer uma pausa do "Enviando transações de Bitcoin" para lermos o [Interlúdio: Usando JQ](04_2__Interlude_Using_JQ.md). \ No newline at end of file diff --git a/pt/04_2__Interlude_Using_JQ.md b/pt/04_2__Interlude_Using_JQ.md new file mode 100644 index 0000000..00b46cf --- /dev/null +++ b/pt/04_2__Interlude_Using_JQ.md @@ -0,0 +1,429 @@ +# Prefácio: Usando o JQ + +A criação de uma transação bruta revelou como resultados mais complexos do ```bitcoin-cli``` que não podem ser salvos facilmente em variáveis de linha de comando. A resposta para isso e usar o JQ, que permite filtrar elementos individuais de dados JSON mais complexos. + +## Instalando o JQ + +O JQ está disponível em um [repositório no Github](https://stedolan.github.io/jq/). Basta fazermos o download para Linux, OS X ou Windows, de acordo com o seu sistema operacional. + +Depois de baixar o binário, podemos instalá-lo em nosso sistema. Se estivermos trabalhando em um VPS Debian, fazendo o passo a passo desse curso, nossa instalação será parecida com esta: +``` +$ mv jq-linux64 jq +$ sudo /usr/bin/install -m 0755 -o root -g root -t /usr/local/bin jq +``` +> :book: ***O que é o JQ?*** O repositório explica melhor, dizendo "O jq é como o sed para dados o JSON - você pode usá-lo para dividir, filtrar, mapear e transformar dados estruturados com a mesma facilidade que o sed, awk, grep e permitem que você brinque com o texto". + +## Usando o JQ para acessar um valor do objeto JSON pelo índice + +**Caso de uso:** _Capturando o hex de uma transação bruta assinada._ + +Na seção anterior, o uso de ```signrawtransaction``` não pareceu ser um bom método devido ao fato de não ser capaz de capturar os dados facilmente em variáveis devido a seu retorno no formato JSON: +``` +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex +{ + "hex": "02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000", + "complete": true +} +``` +Felizmente, o JQ pode facilmente capturar os dados desse tipo! + +Para usar o JQ, vamos executar ```jq``` no backend de um pipe e sempre usar a invocação padrão que é ```jq -r '.'```. O ```-r``` diz ao JQ para diminuir a saída bruta, que funcionará para variáveis de linha de comando, enquanto o ```.``` diz ao JQ para mostrar na tela Protegemos esse argumento com ```''``` porque precisaremos dessa proteção mais tarde conforme nossas invocações ```JQ``` se tornarem mais complexas. + +Para capturar um valor específico de um objeto JSON, basta listar o índice após o ```.```: +``` +$ bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex' +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +``` +Com essa ferramenta em mãos, podemos capturar as informações dos objetos JSON para variáveis na linha de comando: +``` +$ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex') +$ echo $signedtx +02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 +``` +Podemos usar então essas variáveis facilmente e sem erros: +``` +$ bitcoin-cli sendrawtransaction $signedtx +3f9ccb6e16663e66dc119de1866610cc4f7a83079bfec2abf0598ed3adf10a78 +``` +## Usando o JQ para acessar valores únicos do objeto JSON em um array usando o índice + +**Caso de uso:** _Capturando o txid e o vout para um UTXO selecionado._ + +Extrair dados de um objeto JSON é fácil, mas e se esse objeto JSON estiver em uma matriz JSON? O comando ```listunspent``` oferece um ótimo exemplo, porque geralmente contém várias transações diferentes. E se quisermos capturar as informações específicas de _um_ deles? + +Ao trabalhar com um array JSON, a primeira coisa que precisamos fazer é informar ao JQ qual índice acessar. Por exemplo, podemos estar olhando nossas transações no ```listunspent``` e decidimos que queremos trabalhar com a segunda. Podemos usar o ```'. [1]'``` para acessar o primeiro elemento. O ```[]``` diz que estamos referenciando um array JSON e o ```0``` diz que queremos o índice 0. +``` +$ bitcoin-cli listunspent | jq -r '.[1]' +{ + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022, + "confirmations": 9, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true +} +``` +Podemos então capturar um valor individual dessa matriz (1) selecionada usando um pipe _dentro_ dos argumentos JQ; e então o (2) solicitando o valor específico posteriormente, como no exemplo anterior. Isso iria capturar o ```txid``` do primeiro objeto JSON na matriz JSON produzida pelo comando ```listunspent```: +``` +$ bitcoin-cli listunspent | jq -r '.[1] | .txid' +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c +``` +Observe cuidadosamente como os ```''``` circundam toda a expressão JQ _incluindo_ o pipe. + +Este método pode ser usado para preencher variáveis para um UTXO que desejamos utilizar: +``` +$ newtxid=$(bitcoin-cli listunspent | jq -r '.[1] | .txid') +$ newvout=$(bitcoin-cli listunspent | jq -r '.[1] | .vout') +$ echo $newtxid +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c +$ echo $newvout +0 +``` +Pronto! Agora podemos criar uma nova transação bruta usando nosso primeiro UTXO como entrada, sem ter que digitar qualquer uma das informações do UTXO manualmente! + +## Usando o JQ para acessar valores dos objetos JSON correspondentes em um array usando os índices + +**Caso de uso:** _Listar o valor de todos os UTXOs._ + +Ao invés de acessar um único valor específico em um objeto JSON específico, podemos acessar todos os valores específicos em todos os objetos JSON. Isso é feito com ```. []```, Onde nenhum índice é especificado. Por exemplo, podemos listar todos os saldos não gastos: +``` +$ bitcoin-cli listunspent | jq -r '.[] | .amount' +0.0001 +0.00022 +``` + +## Usando o JQ para cálculos simples usando índices + +**Caso de uso:** _Adicionando o valor de todos os UTXOs não gastos._ + +Neste ponto, podemos começar a usar o retorno do JQ para fazermos uma matemática simples. Por exemplo, somar os valores dessas transações não gastas com um script ```awk``` simples nos daria o equivalente ao ```getbalance```: +``` +$ bitcoin-cli listunspent | jq -r '.[] | .amount' | awk '{s+=$1} END {print s}' +0.00032 +$ bitcoin-cli getbalance +0.00032000 +``` + +## Usando o JQ para exibir vários valores de um objeto JSON em um array usando vários índice + +**Caso de uso:** _Listar as informações de uso para todos os UTXOs._ + +O JQ pode capturar facilmente elementos individuais de objetos JSON e arrays e colocar os elementos em variáveis. Esse será o principal uso que iremos fazer nas seções futuras. No entanto, ele também pode ser usado para reduzir grandes quantidades de informações geradas pelo ```bitcoin-cli``` em quantidades razoáveis de informações. + +Por exemplo, podemos querer ver uma lista de todos os nossos UTXOs (```. []```) E obter uma lista de todas as informações mais importantes (```.txid, .vout, .amount```): +``` +$ bitcoin-cli listunspent | jq -r '.[] | .txid, .vout, .amount' +ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36 +0 +0.0001 +91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c +0 +0.00022 +``` +Isso torna mais fácil decidir quais UTXOs gastar em uma transação bruta, mas não é muito bonito. + +Felizmente, o JQ também permite que sejamos mais sofisticados. Podemos usar as ```{}``` para criar novos objetos JSON (para análise adicional ou para um retorno mais bonito). Também podemos definir o nome da nova chave para cada um dos valores. A saída resultante deve ser muito mais intuitiva e menos sujeita a erros (embora, menos útil para jogar as informações diretamente nas variáveis). + +O exemplo a seguir mostra exatamente a mesma análise do ```listunspent```, mas com cada objeto JSON antigo reconstruído como um novo objeto JSON abreviado, com todos os novos valores nomeados com os índices antigos: +``` +$ bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }' +{ + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "amount": 0.0001 +} +{ + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "amount": 0.00022 +} +``` +Podemos, é claro, renomear nossos novos índices conforme acharmos necessário. Não há nada de mágico nos nomes originais: +``` +$ bitcoin-cli listunspent | jq -r '.[] | { tx: .txid, output: .vout, bitcoins: .amount }' +{ + "tx": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "output": 0, + "bitcoins": 0.0001 +} +{ + "tx": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "output": 0, + "bitcoins": 0.00022 +} +``` +## Usando o JQ para acessar os objetos JSON usando um valor pesquisado + +**Caso de uso:** _Pesquisando automaticamente os UTXOs que estão sendo usados em uma transação._ + +As pesquisas JQ até agora são bastante simples: Usamos um índice para pesquisar um ou mais valores em um objeto JSON ou no array. Mas e se quisermos pesquisar um valor em um objeto JSON... usando outro valor? Esse tipo de pesquisa indireta tem aplicabilidade real quando estamos trabalhando com transações criadas usando as UTXOs existentes. Por exemplo, podemos calcular o valor da soma dos UTXOs sendo usados em uma transação, algo de vital importância. + +Este exemplo usa a seguinte transação bruta. Podemos observar que esta é uma transação bruta mais complexa com duas entradas e duas saídas. Aprenderemos como fazer isso nas próximas sessões, mas por enquanto, é necessário sermos capazes de oferecer exemplos robustos. Observe que, ao contrário dos nossos exemplos anteriores, neste, temos dois objetos em nosso array ```vin``` e dois em nosso array ```vout```. +``` +$ bitcoin-cli decoderawtransaction $rawtxhex +{ + "txid": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e", + "hash": "6f83a0b78c598de01915554688592da1d7a3047eacacc8a9be39f5396bf0a07e", + "size": 160, + "vsize": 160, + "version": 2, + "locktime": 0, + "vin": [ + { + "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + }, + { + "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.00000000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 cfc39be7ea3337c450a0c77a839ad0e160739058 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914cfc39be7ea3337c450a0c77a839ad0e16073905888ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mzTWVv2QSgBNqXx7RC56zEhaQPve8C8VS9" + ] + } + }, + { + "value": 0.04500000, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 166692bda9f25ced145267bb44286e8ee3963d26 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914166692bda9f25ced145267bb44286e8ee3963d2688ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "mhZQ3Bih6wi7jP1tpFZrCcyr4NsfCapiZP" + ] + } + } + ] +} +``` + +### Recuperando o(s) valor(es) + +Suponha que saibamos exatamente como essa transação é construída: Sabemos que ela usa dois UTXOs como entrada. Para recuperar o txid para os dois UTXOs, poderíamos usar ```jq``` para consultar o valor .vin da transação e, em seguida, fazer referência ao primeiro índice do .vin e, em seguida, ao valor .txid desse array. Posteriormente, poderíamos fazer o mesmo com o primeiro array e, em seguida, o mesmo com os dois valores .vout de .vin. Simples: +``` +$ usedtxid1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .txid') +$ echo $usedtxid1 +d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c +$ usedtxid2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .txid') +$ echo $usedtxid2 +c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b + +$ usedvout1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .vout') +$ echo $usedvout1 +1 +$ usedvout2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .vout') +$ echo $usedvout2 +1 +``` +No entanto, seria melhor ter um caso geral que salvasse _automaticamente_ todos os txids de nossos UTXOs. + +Já sabemos que podemos acessar todos os ```.txid``` usando um valor do array ```. [] ```. Podemos usar isso para criar uma pesquisa geral no .txid: +``` +$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) +$ echo ${usedtxid[0]} +d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c +$ echo ${usedtxid[1]} +c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b + +$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) +$ echo ${usedvout[0]} +1 +$ echo ${usedvout[1]} +1 +``` +O único truque real aqui é como salvamos as informações usando o shell bash. Ao invés de salvar em uma variável com ```$ (command)```, nós salvamos em um array com ```($ (command))```. Fomos então capazes de acessar os elementos individuais do array bash com uma construção ```$ {variable [n]}```. Ao invés disso, poderíamos acessar todo o array usando a ```$ {variable [@]}```. (E antes que diga algo, ninguém nunca disse que o bash ficaria bonito). + +> :warning: **ATENÇÃO:** Lembre-se sempre de que um UTXO é uma transação _mais_ um vout. Perdemos o vout na primeira vez que escrevemos este exemplo JQ, e ele parou de funcionar quando acabamos com uma situação em que dois ```vouts``` foram enviados da mesma transação. + +### Recuperando o(s) objeto(s) relacionado(s) + +Agora podemos usar as informações salvas no ```txid``` e no ```vout``` para referenciar os UTXOs no ```listunspent```. Para encontrar as informações sobre os UTXOs usados pela transação bruta, precisamos examinar todo o array JSON (```[]```) com as transações não gastas. Podemos então escolher (```select```) objetos JSON individuais que incluem (```contains```) os txids. _Então_ selecionamos (```select```) as transações entre aquelas que _também_ contém (```contêm```) o valor correto. + +O uso de outro nível do pipe é a metodologia padrão do JQ: Pegamos um conjunto de dados, depois a reduzimos para todas as transações relevantes e, em seguida, reduzimos para os valores que foram realmente usados nessas transações. No entanto, os argumentos ```select``` e ```contains``` são algo novo. Eles mostram um pouco da complexidade do JSON que vai além do escopo deste tutorial. Por enquanto, saiba apenas que esta invocação em particular funcionará para capturar objetos correspondentes. + +Para começar de forma simples, vamos selecionar os dois UTXOs, um de cada vez: +``` +$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[0]}'")) | select(.vout | contains('${usedvout[0]}'))' +{ + "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", + "vout": 1, + "address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH", + "scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac", + "amount": 0.9, + "confirmations": 6, + "spendable": true, + "solvable": true +} +$ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[1]}'")) | select(.vout | contains('${usedvout[1]}'))' +{ + "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", + "vout": 1, + "address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q", + "scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac", + "amount": 0.4, + "confirmations": 5, + "spendable": true, + "solvable": true +} +``` +Ao invés disso, um simples bash usando um loop em ```for``` poderia nos dar _todos_ os nossos UTXOs: +``` +$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout'))'; done; +{ + "txid": "d261b9494eb29084f668e1abd75d331fc2d6525dd206b2f5236753b5448ca12c", + "vout": 1, + "address": "miSrC3FvkPPZgqqvCiQycq7io7wTSVsAFH", + "scriptPubKey": "76a91420219e4f3c6bc0f6524d538009e980091b3613e888ac", + "amount": 0.9, + "confirmations": 7, + "spendable": true, + "solvable": true +} +{ + "txid": "c7c7f6371ec19330527325908a544bbf8401191645598301d24b54d37e209e7b", + "vout": 1, + "address": "mzizSuAy8aL1ytFijds7pm4MuDPx5aYH5Q", + "scriptPubKey": "76a914d2b12da30320e81f2dfa416c5d9499d08f778f9888ac", + "amount": 0.4, + "confirmations": 6, + "spendable": true, + "solvable": true +} + +``` +Observe que estamos deixando um pouquinho mais feio nosso array ```$ {# usedtxid [*]}``` para determinar o tamanho dele, em seguida, acessamos cada valor no array ```usedtxid``` e cada valor no array ```usedvout``` paralelo, os colocando em variáveis mais simples para termos um acesso menos feio. + +## Usando o JSON para cálculos simples usando os valores + +**Caso de uso:** _Calcular automaticamente o valor dos UTXOs usados em uma transação._ + +Agora podemos ir um passo adiante e solicitar o .amount (ou qualquer outro valor do índice do JSON) dos UTXOs que estamos recuperando. + +Este exemplo repete o uso dos arrays ```$usedtxid``` e ```$usedvout``` definidos da seguinte forma: + +``` +$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) +$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) +``` + +O mesmo script ```for``` pode ser usado para percorrer os arrays, mas com um pipe adicionado no JQ que produz o valor ```amount``` para cada um dos UTXOs selecionados. + +``` +$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done; +0.9 +0.4 +``` + +Neste ponto, podemos somar os .amounts com um script ```awk```, para realmente ver quantas moedas estão nos UTXOs gastos na transação: + +``` +$ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done | awk '{s+=$1} END {print s}' +1.3 +``` + +Perfeito! + +## Usando o JQ para cálculos complexos + +**Caso de uso:** _Calcular a taxa de uma transação._ + +Descobrir a taxa de transação completa neste ponto requer apenas mais um pouco de matemática: Bastando determinar quanto dinheiro está passando pelo .vout. Este é um uso simples de JQ onde apenas usamos o ```awk``` para somar o ```valor``` de todas as informações do ```vout```: + +``` +$ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}' +1.045 +``` + +Para completar o cálculo da taxa de transação, vamos subtrair o .vout .amount (1.045) do .vin .amount (1.3). +Para fazer isso, precisaremos instalar o ```bc```: + +``` +$ sudo apt-get intall bc +``` + +Se juntarmos tudo, iremos criar uma calculadora completa com apenas um script de cinco linhas: + +``` +$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) +$ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout')) +$ btcin=$(for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done | awk '{s+=$1} END {print s}') +$ btcout=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}') +$ echo "$btcin-$btcout"| /usr/bin/bc +.255 +``` + +E esse também é um bom exemplo de por que precisamos verificar nossas suas taxas: Pretendíamos enviar uma taxa de transação com 5.000 satoshis, mas invés disso enviamos pagando 255.000 satoshis de taxa. Ops! + +> :warning: **Atenção:** A primeira vez que escrevemos esta lição, realmente calculamos mal a nossa taxa e não a vimos até que executamos nossa calculadora de taxas. É *tão* fácil, que nosso dinheiro acabou. (O exemplo acima é, na verdade, de nossa segunda iteração da calculadora, e dessa vez cometemos o erro de propósito). + +Para mais magia usando o JSON (e se alguma coisa não estiver clara), leia o [Manual JSON](https://stedolan.github.io/jq/manual/) e o [Livro de Receitas do JSON](https://github.com/stedolan/jq/wiki/Cookbook). Estaremos usando o JQ regularmente nos exemplos futuros. + +## Fazendo alguns aliases novos + +O código JQ pode ser um pouco pesado, então devemos considerar adicionar algumas invocações mais longas e interessantes ao nosso ```~/.bash_profile```. + +Sempre que estivermos procurando por uma grande massa de informações em uma saída de objeto JSON por um comando ```bitcoin-cli```, precisamos considerar escrever um alias para reduzi-lo exatamente ao que desejamos observar. + +``` +alias btcunspent="bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }'" +``` + +## Executando o script de taxa de transação + +O [script de cálculo de taxa](src/04_2_i_txfee-calc.sh) está disponível no diretório src/. Você pode baixá-lo e salvá-lo como ```txfee-calc.sh```. + +> :warning: **Atenção:** Este script não foi verificado extensivamente. Se for usá-lo para verificar as taxas de transação reais, só deve fazê-lo depois de fazer uma verificação pessoal dos valores. + +Certifique-se de que as permissões no script estejam corretas: + +``` +$ chmod 755 txfee-calc.sh +``` + +Podemos então, executar o script da seguinte maneira: + +``` +$ ./txfee-calc.sh $rawtxhex +.255 +``` + +Também podemos criar um alias: + +``` +alias btctxfee="~/txfee-calc.sh" +``` + +## Resumo do Usando o JQ + +O JQ facilita a extração de informações de arrays e objetos JSON. Ele também pode ser usado em scripts shell para cálculos bastante complexos que tornarão nossa vida mais fácil. + +## O que vem depois? + +Continue "Enviando Transações de Bitcoin" na sessão [§4.3 Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md). \ No newline at end of file diff --git a/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md b/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md new file mode 100644 index 0000000..2ff9957 --- /dev/null +++ b/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md @@ -0,0 +1,97 @@ +# 4.3 Criando uma transação bruta com argumentos nomeados + +Às vezes, pode ser assustador descobrir a ordem correta dos argumentos para um comando ```bitcoin-cli```. Felizmente, podemos usar _ argumentos nomeados_ como alternativa. + +> :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.14.0. Se usarmos os scripts de configuração do tutorial, o que é importante fazer, precisamos verificar novamente a versão se tiver algum problema. Há também um bug no uso do comando ```createrawtransaction``` usando argumentos nomeados que presumivelmente serão corrigidos na versão 0.14.1. + +## Criando um alias do argumento nomeado + +Para usar um argumento nomeado, devemos executar o ```bitcoin-cli``` com o argumento ```-named```. Se planejamos fazer isso regularmente, provavelmente precisaremos criar um alias: +``` +alias bitcoin-cli="bitcoin-cli -named" +``` +Como de costume, isso é apenas para facilitar o uso, mas continuaremos usando todos os comandos para manter a clareza. + +## Testando um argumento nomeado + +Para saber quais são os nomes dos argumentos de um comando, precisamos consultar o ```bitcoin-cli help```. Ele listará os argumentos com a ordem adequada, mas agora também fornecerá nomes para cada um deles. + +Por exemplo, `bitcoin-cli help getbalance` lista estes argumentos: + + 1. dummy [costumava ser account] + 2. minconf + 3. include_watchonly + 4. avoid_reuse + +O exemplo seguinte mostra um uso tradicional e não intuitivo do ```getbalance``` usando o argumento de confirmação mínimo: +``` +$ bitcoin-cli getbalance "*" 1 +``` +Com argumentos nomeados, podemos esclarecer o que estamos fazendo, o que também minimiza os erros: +``` +$ bitcoin-cli -named getbalance minconf=1 +``` + +## Testando uma transação bruta + +Veja como seriam os comandos para enviar uma transação bruta com argumentos nomeados: +``` +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ recipient="n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00001 }''') +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex +{ + "txid": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", + "hash": "2b59c31bc232c0399acee4c2a381b564b6fec295c21044fbcbb899ffa56c3da5", + "version": 2, + "size": 85, + "vsize": 85, + "weight": 340, + "locktime": 0, + "vin": [ + { + "txid": "ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36", + "vout": 0, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 0.00001000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + ] + } + } + ] +} + +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +e70dd2aa13422d12c222481c17ca21a57071f92ff86bdcffd7eaca71772ba172 +``` +Pronto! Enviamos outra transação bruta, mas desta vez usando argumentos nomeados para ter maior clareza e redução de erros. + +> :warning: **AVISO DE VERSÃO:** É aqui que o bug no Bitcoin Core 0.14 aparece: O argumento ```inputs``` no ```createrawtransaction``` tem o nome ```transactions``` incorreto. Portanto, se estivermos no Bitcoin Core 0.14.0, substitua o argumento nomeado ```inputs``` por ```transactions``` para este e também para os exemplos futuros. No entanto, a partir do Bitcoin Core 0.14.1, esse código deve funcionar normalmente. + +## Resumo do Criando uma transação bruta com argumentos nomeados + +Executando o ```bitcoin-cli``` com o argumento ```-named```, podemos usar argumentos nomeados ao invés de depender de argumentos ordenados. O comando ```bitcoin-cli help``` sempre mostrará o nome correto para cada argumento. Isso pode resultar em um código mais robusto, mais fácil de ler e menos sujeito a erros. + +_À partir de agora, usaremos argumentos nomeados para todos os exemplos futuros, para maior clareza e para estabelecer as melhores práticas. No entanto, também mostraremos todos os argumentos na ordem correta. Portanto, se preferir não usar os argumentos nomeados, apenas retire o argumento ```-named``` e todos os ```name =``` que os exemplos devem continuar funcionando corretamente._ + +## O que vem depois? + +Continue "Enviando Transações de Bitcoin" na sessão [§4.4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md). \ No newline at end of file diff --git a/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md new file mode 100644 index 0000000..5a3b40e --- /dev/null +++ b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -0,0 +1,187 @@ +# 4.4: Enviando bitcoins usando transações brutas + +Conforme observado no início deste capítulo, a interface ```bitcoin-cli``` oferece três maneiras principais de enviar moedas. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) falou sobre como enviá-la pela primeira vez, usando o comando ```sendtoaddress```. Desde então, estamos construindo coisas mais detalhadas sobre como enviar moedas de uma segunda maneira, com transações brutas. A sessão [§4.2](04_2_Creating_a_Raw_Transaction.md) nos ensinou como criar uma transação bruta, um [Prefácio](04_2__Interlude_Using_JQ.md) explicou sobre o JQ e a sessão [§4.3](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) demonstrou os argumentos nomeados. + +Agora podemos colocá-los juntos e realmente enviar fundos usando uma transação bruta. + +## Criando uma endereço de troco + +Nosso exemplo de transação bruta na seção §4.2 era simples demais: Enviamos um UTXO inteiro para um novo endereço. Com mais frequência, iremos desejar enviar a alguém uma quantia em dinheiro que não corresponde a um UTXO. Mas, devemos nos lembrar que o excesso de dinheiro de um UTXO que não é enviado ao destinatário se torna apenas a taxa de transação. Então, como enviar para alguém apenas uma parte de um UTXO, enquanto guardamos o resto pra gente? + +A solução é _enviar_ o restante dos fundos para um segundo endereço, um endereço de troco que criamos em nossa carteira especificamente para recebê-los: +``` +$ changeaddress=$(bitcoin-cli getrawchangeaddress legacy) +$ echo $changeaddress +mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h +``` +Observe que isso usa uma nova função: ```getrawchangeaddress```. É basicamente é a mesma coisa que o ```getnewaddress```, mas é otimizado para uso como um endereço de truco em uma transação bruta, portanto, não faz coisas como criar entradas em nossa lista de endereços. Selecionamos novamente o endereço ```legacy```, ao invés de usar o padrão ```bech32```, simplesmente para consistência. Esta é uma situação em que teria sido seguro gerar um endereço Bech32 padrão, apenas usando ```bitcoin-cli getrawchangeaddress```, porque ele seria enviado e recebido por nós em nosso node Bitcoin Core, que tem suporte integral a isso. Mas, estamos adiantando as coisas. Vamos mudar sobre como mudar o endereço para Bech32 na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md). + +Agora temos um endereço adicional em nossa carteira, para que possamos receber o troco de um UTXO! Para usá-lo, precisaremos criar uma transação bruta com duas saídas. + +## Escolhendo os UTXOs suficientes + +Nosso exemplo de transação bruta era simples também de outra maneira: Assumia que havia dinheiro suficiente em um único UTXO para cobrir toda a transação. Frequentemente, esse será o caso, mas às vezes desejaremos criar transações que gastem mais dinheiro do que temos em um único UTXO. Para fazer isso, devemos criar uma transação bruta com duas (ou mais) entradas. + +## Escrevendo uma transação bruta real + +Para resumir: A criação de uma transação bruta real para enviar moedas, às vezes, requer múltiplas entradas e, quase sempre, múltiplas saídas, uma das quais é um endereço de troco. Estaremos criando esse tipo de transação mais realista, um exemplo que mostra um caso de uso da vida real, enviando fundos por meio da segunda metodologia do Bitcoin, as transações brutas. + +Vamos usar nossos UTXOs 0 e 2: +``` +$ bitcoin-cli listunspent +[ +[ + { + "txid": "0619fecf6b2668fab1308fbd7b291ac210932602a6ac6b8cc11c7ae22c43701e", + "vout": 1, + "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + "label": "", + "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", + "amount": 0.00899999, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 15, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + }, + { + "txid": "0df23a9dba49e822bbc558f15516f33021a64a5c2e48962cec541e0bcc79854d", + "vout": 0, + "address": "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + "label": "", + "scriptPubKey": "76a914ad1ed1c5971b2308f89c1362d4705d020a40e8e788ac", + "amount": 0.00100000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/4']03eae28c93035f95a620dd96e1822f2a96e0357263fa1f87606a5254d5b9e6698f)#wwnfx2sp", + "safe": true + } +] + +``` +Em nosso exemplo, enviaremos 0,009 BTC, que é (um pouco) maior do que qualquer um de nossos UTXOs. Para isso, será necessário que os combinemos e, em seguida, vamos usar nosso endereço de troco para recuperar os fundos não gastos. + +### Configurando as variáveis + +Já temos as variáveis ​​```$changeaddress``` e ```$recipient``` dos exemplos anteriores: +``` +$ echo $changeaddress +mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h +$ echo $recipient +n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +``` +Também precisamos registrar o txid e vout para cada um de nossos dois UTXOs. Tendo identificado os UTXOs que queremos gastar, podemos usar as técnicas do JQ para garantir que o acesso a eles esteja livre de erros: +``` +$ utxo_txid_1=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') +$ utxo_vout_1=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') +$ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') +$ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') +``` + +### Escrevendo a transação + +Escrever a transação bruta real é surpreendentemente simples. Tudo o que precisamos fazer é incluir um objeto JSON adicional separado por vírgula na matriz JSON de entradas e um par de valores-chave adicional separado por vírgula em um objeto JSON de saídas. + +Aqui temos um exemplo. Observe as múltiplas entradas após o argumento ```inputs``` e as múltiplas saídas após o argumento ```outputs```. +``` +$ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.009, "'$changeaddress'": 0.0009 }''') +``` +Fomos _muito_ cuidadosos em calcular a quantidade. Esses dois UTXOs contêm 0,00999999 BTC. Depois de enviar 0,009 BTC, teremos 0,00099999 BTC restantes. Escolhemos 0,00009999 BTC como a nossa taxa de transação. Para acomodar essa taxa, definimos o troco como sendo 0,0009 BTC. Se não tivermos prestado atenção nisso, e definido nosso troco para 0,00009 BTC, essa quantidade de BTC adicional seria enviado para os mineradores! Se tivéssemos esquecido de fazer o troco, todo o excesso teria desaparecido. Portanto, novamente, _ tenha cuidado_. + +Felizmente, podemos verificar três vezes com o alias ```btctxfee``` do Prefácio do JQ: +``` +$ ./txfee-calc.sh $rawtxhex2 +.00009999 +``` + +### Concluindo + +Agora podemos assinar, selar e entregar nossa transação, e ela é sua (e do faucet): +``` +$ signedtx2=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex2 | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx2 +e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d +``` + +### Esperando + +Como de costume, nossas moedas estarão no fluxo por um tempo: O troco ficará indisponível até que a transação seja realmente confirmada e um novo UTXO seja nos dado. + +Mas, em 10 minutos ou menos (provavelmente), teremos o dinheiro restante de volta e totalmente utilizável novamente. Por enquanto, ainda precisamos esperar: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 15, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] +``` +E o troco eventualmente voltará para nós: +``` +[ + { + "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", + "vout": 1, + "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", + "amount": 0.00090000, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022000, + "confirmations": 16, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } +] +``` +Este também pode ser um bom momento para revisitar um explorador de blockchain, para que possamos ver mais intuitivamente como as entradas, saídas e as taxas estão dispostas na transação: [e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://mempool.space/pt/testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d). + +## Resumo do Enviando bitcoins usando transações brutas + +Para enviar moedas usando transações brutas, precisamos criar uma transação bruta com uma ou mais entradas (para ter fundos suficientes) e uma ou mais saídas (para recuperar usando o troco). Então, podemos seguir nosso procedimento normal de usar o ```createrawtransaction``` com argumentos nomeados junto com o JQ, conforme descrito nas seções anteriores. + +> :fire: ***Qual é o ponto positivo de enviar moedas com transações brutas?*** +> _As vantagens._ Oferece maior controle. Se o nosso objetivo é escrever um programa ou script Bitcoin mais complexo, provavelmente usaremos as transações brutas para saber exatamente o que está acontecendo. Essa também é a situação mais _segura_ para usar transações brutas, porque podemos garantir que não cometeremos nenhum erro na parte da programação. +> _As desvantagens._ É muito fácil perder dinheiro. Não há avisos, bloqueios e barreiras na programação, a não ser que as criemos. Também é tudo muito misterioso. A formatação é desagradável, mesmo usando a interface ```bitcoin-cli``` que é fácil de usar, e temos que fazer muitas pesquisas e cálculos manualmente. + +## O que vem depois? + +Veja uma forma alternativa de inserir comandos no [Prefácio: Usando o JQ] (04_4__Interlude_Using_Curl.md). + +Ou, se preferir pular, o que é francamente uma digressão, podemos aprender mais com "Enviando Transações de Bitcoin" na sessão [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file diff --git a/pt/04_4__Interlude_Using_Curl.md b/pt/04_4__Interlude_Using_Curl.md new file mode 100644 index 0000000..a6957ac --- /dev/null +++ b/pt/04_4__Interlude_Using_Curl.md @@ -0,0 +1,314 @@ +# Prefácio: Acessando o Bitcoind com Curl + +O ```bitcoin-cli``` é, em última análise, apenas um invólucro. É uma forma de interagir com ```bitcoind``` a partir da linha de comando, fornecendo acesso simplificado aos seus diversos comandos RPC. Mas o RPC pode, é claro, ser acessado diretamente. É disso que iremos falar nessa sessão: Como nos conectarmos diretamente ao RPC com o comando ```curl```. + +It won't be used much in the future chapters, but it's an important building block that you can see as an alternative access to `bitcoind` is you so prefer. +Não será muito usado nos próximos capítulos, mas essas informações serão importantes caso queiramos uma alternativa para acessar o ```bitcoind```. + +## Conhecendo o Curl + +O ```curl```, abreviação de "ver URL", é uma ferramenta de linha de comando que permite acessar URLs diretamente usando a linha de comando. É uma maneira fácil de interagir com servidores como o ```bitcoind```, que ficam ouvindo as portas da internet e conversam utilizando uma variedade de protocolos. O Curl também está disponível como uma biblioteca para muitas linguagens de programação, como C, Java, PHP e Python. Então, depois de saber como trabalhar com o Curl, teremos uma base sólida para usar várias APIs diferentes. + +Para usar o ```curl``` com o ```bitcoind```, devemos saber três coisas: O formato padrão, o nome de usuário e senha e a porta correta. + +### Conhecendo o formato + +Os comandos ```bitcoin-cli``` estão todos vinculados aos comandos RPC no ```bitcoind```. Isso torna a transição do uso de ```bitcoin-cli``` para o uso do ```curl``` muito simples. Na verdade, se olharmos qualquer uma das páginas de ajuda do ```bitcoin-cli```, veremos que eles listam não apenas os comandos ```bitcoin-cli```, mas também os comandos ```curl``` paralelos. Por exemplo, aqui temos o resultado do comando ```bitcoin-cli help getmininginfo```: +``` +$ bitcoin-cli help getmininginfo +getmininginfo + +Returns a json object containing mining-related information. +Result: +{ (json object) + "blocks" : n, (numeric) The current block + "currentblockweight" : n, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled) + "currentblocktx" : n, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled) + "difficulty" : n, (numeric) The current difficulty + "networkhashps" : n, (numeric) The network hashes per second + "pooledtx" : n, (numeric) The size of the mempool + "chain" : "str", (string) current network name (main, test, regtest) + "warnings" : "str" (string) any network and blockchain warnings +} + +Examples: +> bitcoin-cli getmininginfo +> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ +``` +E tem o comando ```curl```, no final da tela de ajuda! Este comando um tanto longo tem quatro partes principais: (1) Uma lista do nome de usuário; (2) Um sinalizador ```--data-binary```; (3) Um objeto JSON que diz ao ```bitcoind``` o que fazer, incluindo um array JSON com os parâmetros e; (4) Um cabeçalho HTTP que inclui a URL do ```bitcoind```. + +Quando estamos trabalhando com o ```curl```, muitos desses argumentos do ```curl``` permanecerão os mesmos de um comando para outro, apenas as entradas ```method``` e ```params``` no array JSON normalmente mudam. No entanto, precisaremos saber como preencher o nome do usuário e endereço da URL para que funcione, antes de mais nada! + +_Sempre que não tivermos certeza sobre como usar o curl no RPC, basta usarmos a ajuda do bitcoin-cli e continuar._ + +### Descobrindo o nome de usuário + +Para falar com a porta do ```bitcoind```, precisamos de um nome de usuário e senha. Eles foram criados como parte da configuração inicial do Bitcoin e podem ser encontrados no arquivo `~/.bitcoin/bitcoin.conf`. + +Por exemplo, aqui está nossa configuração atual: +``` +$ cat ~/.bitcoin/bitcoin.conf +server=1 +dbcache=1536 +par=1 +maxuploadtarget=137 +maxconnections=16 +rpcuser=StandUp +rpcpassword=8eaf562eaf45c33c3328bc66008f2dd1 +rpcallowip=127.0.0.1 +debug=tor +prune=550 +testnet=1 +mintxfee=0.001 +txconfirmtarget=1 +[test] +rpcbind=127.0.0.1 +rpcport=18332 +[main] +rpcbind=127.0.0.1 +rpcport=8332 +[regtest] +rpcbind=127.0.0.1 +rpcport=18443 +``` +Nosso nome de usuário é ```StandUp``` e nossa senha é ```8eaf562eaf45c33c3328bc66008f2dd1```. + +> **Atenção:** Obviamente, não é muito seguro ter essas informações em um arquivo de texto simples. A partir do Bitcoin Core 0.12, podemos omitir o ```rpcpassword``` do arquivo ```bitcoin.conf``` e fazer com que o ```bitcoind``` gere um novo cookie sempre que iniciarmos o serviço. A desvantagem disso é que torna o uso de comandos RPC por outros aplicativos, como os detalhados neste capítulo, mais difícil. Então, vamos ficar com as informações simples do ```rpcuser``` e ```rpcpassword``` por enquanto, mas para softwares em produção, é importante considerarmos essa alteração para cookies. + +A maneira segura de usar o RPC com ```bitcoind``` é a seguinte: +``` +$ curl --user StandUp --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ +Enter host password for user 'bitcoinrpc': +``` +Conforme observado, nossa senha será solicitada. + +> :link: **TESTNET vs MAINNET:** A Testnet usa uma URL com a porta 18332 e a mainnet usa uma URL com a porta 8332. Se tivermos alguma dúvida, basta olharmos nosso ```bitcoin.conf```. As configurações estão todas lá. + +A maneira insegura e errada de fazer isso é a seguinte: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ +``` +> **Atenção:** Digitar a senha na linha de comando pode colocá-la na tabela de processos e/ou salvá-la em um histórico qualquer. Isso é ainda menos recomendado do que colocá-la em um arquivo, exceto para testes utilizando a testnet. Se quisermos fazer em qualquer outro lugar, precisamos nos certificar de saber o que estamos fazendo! + +### Conhecendo os comandos e os parâmetros + +Com tudo isso em mãos, estamos prontos para enviar os comandos RPC padrão com o ```curl```, mas ainda precisamos saber como incorporar os dois elementos que tendem a mudar no comando ```curl```. + +O primeiro é o ```method```, que é o método RPC que está sendo utilizado. Isso geralmente deve corresponder aos nomes de comando que alimentamos no ```bitcoin-cli``` por muito tempo. + +O segundo é o ```params```, que é uma matriz JSON de parâmetros. Eles são iguais aos argumentos (ou argumentos nomeados) que estamos usando. Eles também são a parte mais confusa do ```curl```, em grande parte porque são um array estruturado ao invés de uma simples lista. + +Esta é a aparência de algumas matrizes de parâmetros: + + * `[]` — Um array vazio; + * `["000b4430a7a2ba60891b01b718747eaf9665cb93fbc0c619c99419b5b5cf3ad2"]` — Um array com dados; + * `["'$signedhex'"]` — Um array com uma variável; + * `[6, 9999999]` — Uma array com dois parâmetros; + * `{}` - Um objeto vazio; + * `[''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.298, "'$changeaddress'": 1.0}'']` — Um array com um array contendo um objeto e um objeto vazio. + +## Obtendo a informação + +Agora podemos enviar nosso primeiro comando ```curl``` acessando o RPC ```getmininginfo```: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ +{"result":{"blocks":1772428,"difficulty":10178811.40698772,"networkhashps":91963587385939.06,"pooledtx":61,"chain":"test","warnings":"Warning: unknown new rules activated (versionbit 28)"},"error":null,"id":"curltest"}``` +Note that we provided the method, `getmininginfo`, and the parameter, `[]`, but that everything else was the standard `curl` command line. +``` +> **Atenção:** Se obtivermos como resultado o seguinte erro: "Failed to connect to 127.0.0.1 port 8332: Connection refused", precisamos nos certificar de que uma linha como ```rpcallowip = 127.0.0.1``` esteja configurada no ```~/.bitcoin/bitcoin.conf```. Se ainda não funcionar, precisaremos permitir o acesso à porta 18332 (ou 8332) do nosso host local. Nossa configuração padrão do [Capítulo 2: Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) deve fazer tudo isso. + +The result is another JSON array, which is unfortunately ugly to read if you're using `curl` by hand. Fortunately, you can clean it up simply by piping it through `jq`: +O resultado é outro array JSON, que infelizmente é ruim de se ler se estivermos usando o ```curl``` manualmente. Felizmente, podemos limpá-lo simplesmente usando o ```jq```: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed +100 295 100 218 100 77 72666 25666 --:--:-- --:--:-- --:--:-- 98333 +{ + "result": { + "blocks": 1772429, + "difficulty": 10178811.40698772, + "networkhashps": 90580030969896.44, + "pooledtx": 4, + "chain": "test", + "warnings": "Warning: unknown new rules activated (versionbit 28)" + }, + "error": null, + "id": "curltest" +} +``` +Você verá um pouco de relatório de conectividade à medida que os dados são baixados, então, quando os dados chegarem a ```jq```, tudo será corretamente identado. Estaremos omitindo as informações do download nos próximos exemplos. + +## Manipulando nossa carteira + +Embora já estejamos acessando o ```bitcoind``` diretamente, ainda teremos acesso à funcionalidade de carteira, porque ela está amplamente armazenada no próprio ```bitcoind```. + +### Pesquisando endereços + +Usando o RPC ```getaddressesbylabel``` para listar todos os nossos endereços atuais: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getaddressesbylabel", "params": [""] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": { + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE": { + "purpose": "receive" + }, + "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff": { + "purpose": "receive" + }, + "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B": { + "purpose": "receive" + }, + "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d": { + "purpose": "receive" + }, + "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6": { + "purpose": "receive" + }, + "tb1qmtucvjtga68kgrvkl7q05x4t9lylxhku7kqdpr": { + "purpose": "receive" + } + }, + "error": null, + "id": "curltest" +} +``` +Este é o nosso primeiro exemplo de um parâmetro real, ```" "```. Este é o parâmetro ```label``` obrigatório para o ```getaddressesbylabel```, mas todos os nossos endereços estão sob o rótulo padrão, então nada de especial foi necessário neste momento. + +O resultado é uma lista de todos os endereços que foram usados na nossa carteira. Alguns dos quais presumivelmente possuem saldo. + +### Pesquisando pelos saldos + +Use o RPC ```listunspent``` para listar os saldos que temos disponíveis: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": [ + { + "txid": "e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d", + "vout": 1, + "address": "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + "scriptPubKey": "76a91432db726320e4ad170c9c1ee83cd4d8a243c3435988ac", + "amount": 0.0009, + "confirmations": 4, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/1'/2']02881697d252d8bf181d08c58de1f02aec088cd2d468fc5fd888c6e39909f7fabf)#p6k7dptk", + "safe": true + }, + { + "txid": "91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c", + "vout": 0, + "address": "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + "label": "", + "scriptPubKey": "76a9142d573900aa357a38afd741fbf24b075d263ea6e088ac", + "amount": 0.00022, + "confirmations": 19, + "spendable": true, + "solvable": true, + "desc": "pkh([d6043800/0'/0'/3']0278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132)#nhjc3f8y", + "safe": true + } + ], + "error": null, + "id": "curltest" +} +``` +Esta é quase exatamente a mesma saída que recebemos quando digitamos ```bitcoin-cli listunspent```, mostrando como as duas interfaces estão intimamente ligadas. Se nenhuma limpeza ou ajuda extra for necessária, então o ```bitcoin-cli``` apenas produzirá o RPC. Simples assim! + +### Criando um endereço + +Depois de saber onde estão os saldos, a próxima etapa na elaboração de uma transação é obter um endereço de alteração. Agora provavelmente já pegamos o jeito e sabemos que para os comandos RPC simples, tudo que precisamos fazer é ajustar o ```method``` no comando ```curl```: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "mrSqN37TPs89GcidSZTvXmMzjxoJZ6RKoz", + "error": null, + "id": "curltest" +} + +``` +Neste ponto, podemos até mesmo voltar à nossa prática padrão de salvar os resultados em variáveis com a ajuda adicional do `jq`: +``` +$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') +$ echo $changeaddress +mqdfnjgWr2r3sCCeuTDfe8fJ1CnycF2e6R +``` +Não precisamos nos preocupar com as informações do download. Ele irá para o ```STDERR``` e será exibido em nossa tela, enquanto os resultados irão para o ```STDOUT``` e serão salvos em nossa variável. + +## Criando uma transação + +Agora estamos prontos para criar uma transação com o ```curl```. + +### Preparando as variáveis + +Assim como no ```bitcoin-cli```, para criar uma transação usando o Curl com o RPC, devemos primeiro salvar nossas variáveis. A única mudança aqui é que o ```curl``` cria um objeto JSON que inclui um valor-chave ```result```, então sempre precisaremos usar o pipe (```|```) através da tag ```.result``` antes de fazer qualquer outra coisa. + +Este exemplo configura nossas variáveis para usar o BTC de 1.2985 em fundos listados na primeira transação não gasta acima: +``` +$ utxo_txid=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .txid') +$ utxo_vout=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .vout') +$ recipient=mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf +$ changeaddress=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') + +$ echo $utxo_txid +e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d +$ echo $utxo_vout +1 +$ echo $recipient +mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf +$ echo $changeaddress +n2jf3MzeFpFGa7wq8rXKVnVuv5FoNSJZ1N +``` + +### Criando a transação + +A transação criada com o ```curl``` é muito semelhante à transação criada com o ```bitcoin-cli```, mas com algumas diferenças sutis: +``` +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "02000000010d6acd0356db222ca3a7ee7fa1e3044316223ceec1f64b58aeb2e0de921007e70100000000ffffffff0230750000000000001976a914ac19d3fd17710e6b9a331022fe92c693fdf6659588ac50c30000000000001976a9147021efec134057043386decfaa6a6aa4ee5f19eb88ac00000000", + "error": null, + "id": "curltest" +} +``` +O coração da transação é, obviamente, o array JSON ```params```, que estamos colocando em uso total pela primeira vez. + +Podemos observar que todos os ```params``` estão alojados nos ```[]``` para marcar o array de parâmetros. + +Nós também variamos as citações de como as coisas funcionavam no ```bitcoin-cli```, para iniciar e terminar cada array e objeto dentro do array ```params``` com ```''``` ao invés do tradicional ```'' '```. Isso porque todo o conjunto de argumentos JSON já tem um ```'``` em torno dele. Como de costume, basta dar uma olhada na bizarra citação do shell e se acostumar com isso. + +No entanto, há uma última coisa a ser observada neste exemplo, e pode ser _enlouquecedor_ se não tivermos percebido. Quando executamos um comando ```createrawtransaction``` com ```bitcoin-cli```, o array JSON de entradas e o objeto JSON de saídas eram parâmetros distintos, portanto, foram separados por um espaço. Agora, porque eles são parte do array JSON ```params```, eles são separados por uma vírgula (```,```). Se não tivermos percebido isso obteremos um ```parse error``` sem muitas informações. + +> **Atenção:** Todo mundo já teve problemas para depurar o ```curl```, não é mesmo? Para resolver isso basta adicionar o argumento ```--trace-ascii/tmp/foo```. Informações completas sobre o que está sendo enviado ao servidor serão salvas em ```/tmp/foo``` (ou qualquer nome de arquivo que quisermos informar). + +Depois de verificarmos se as coisas estão funcionando, provavelmente iremos desejar salvar o código hexadecimal em uma variável: +``` +$ hexcode=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') +``` + +### Assinando e enviando + +Assinar e enviar a nossa transação usando ```curl``` é bem simples, basta usar os seguintes comandos do RPC ```signrawtransactionwithwallet``` e ```sendrawtransaction```: + +``` +$ signedhex=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "signrawtransactionwithwallet", "params": ["'$hexcode'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .hex') + +$ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "sendrawtransaction", "params": ["'$signedhex'"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' +{ + "result": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", + "error": null, + "id": "curltest" +} +``` +## Resumo do Acessando o Bitcoind com Curl + +Terminando esta seção, podemos sentir que acessar o ```bitcoind``` através de ```curl``` é muito parecido com acessá-lo através de ```bitcoin-cli```, porém, é mais complicado. E estamos certos. O ```bitcoin-cli``` tem funcionalidade RPC bem completa, então qualquer coisa que fizermos através do ```curl``` provavelmente poderemos fazer através do ```bitcoin-cli```. É por isso que vamos continuar nos concentrando no ```bitcoin-cli``` após esta digressão. + +Mas ainda há razões para usar ```curl``` ao invés do ```bitcoin-cli```: + +_Qual é o poder do curl?_ Obviamente, o ```curl``` elimina um nível intermediário. Ao invés de trabalhar com o ```bitcoin-cli```, que envia comandos RPC para o ```bitcoind```, estamos enviando esses comandos RPC diretamente para ele. Isso permite uma programação mais robusta, porque não precisamos nos preocupar com as coisas inesperadas que o ```bitcoin-cli``` pode fazer ou como isso pode mudar com o tempo. No entanto, também estamos dando os primeiros passos para usar uma linguagem de programação mais abrangente do que as opções pobres oferecidas por um script de shell. Como veremos nos últimos capítulos deste livro, podemos realmente ver que as bibliotecas curl são outras funções que acessam os comandos RPC em uma variedade de linguagens de programação: Mas isso ainda está muito longe, ainda. + +## O que vem depois? + +Aprenda mais uma maneira de "Enviando Transações de Bitcoin" com [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file diff --git a/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md b/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md new file mode 100644 index 0000000..91926ae --- /dev/null +++ b/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md @@ -0,0 +1,171 @@ +# 4.5: Enviando bitcoins usando transações brutas automatizadas + +Este capítulo apresenta três maneiras de enviar fundos por meio da interface cli do Bitcoin. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) descreveu como fazer isso com um comando simples, a sessão [§4.4](04_4_Sending_Coins_with_a_Raw_Transaction.md) detalhou como usar uma transação bruta mais perigosa. Esta seção fica no meio termo de ambas, mostrando como tornar as transações brutas mais simples e seguras. + +## Deixando o Bitcoin fazer os cálculos para nós + +A metodologia para transações brutas automatizadas é simples: Criamos uma transação bruta, mas usamos o comando ```fundrawtransaction``` para pedir ao bitcoind para executar os cálculos para nós. + +Para usar este comando, precisaremos garantir que nosso arquivo ```~/.bitcoin/bitcoin.conf``` contenha as variáveis racionais para calcular as taxas de transação. Podemos consultar a sessão [§4.1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md) para obter mais informações sobre isso. + +Vamos usar números conservadores, por isso sugerimos adicionar o seguinte ao `bitcoin.conf`: +``` +mintxfee=0.0001 +txconfirmtarget=6 +``` +Para manter o tutorial em constante movimento (em outras palavras, para movimentarmos nosso dinheiro rápido sem ficar esperando muito), sugerimos o seguinte: +``` +mintxfee=0.001 +txconfirmtarget=1 +``` + +## Criando uma transação bruta + +Para usar o ```fundrawtransaction``` primeiro precisamos criar uma transação bruta básica que liste _nenhuma_ entrada e _nenhuma_ mudança de endereço. Apenas listaremos o nosso destinatário e quanto desejamos enviar, neste caso ```$recipient``` e ```0,0002``` BTC. +``` +$ recipient=n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi +$ unfinishedtx=$(bitcoin-cli -named createrawtransaction inputs='''[]''' outputs='''{ "'$recipient'": 0.0002 }''') +``` + +## Financiando nossa transação bruta + +Dizemos ao ```bitcoin-cli``` para financiar essa transação básica: +``` +$ bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx +{ + "hex": "02000000012db87641c6a21e5a68b20c226428544978e6ac44964d5d8060d7388000c584eb0100000000feffffff02204e0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac781e0000000000001600140cc9cdcf45d4ea17f5227a7ead52367aad10a88400000000", + "fee": 0.00022200, + "changepos": 1 +} +``` +Isso fornece muitas informações úteis, mas uma vez que tenhamos certeza de como funciona, vamos querer usar o JQ para salvar nosso hex em uma variável, como de costume: +``` +$ rawtxhex3=$(bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx | jq -r '.hex') +``` +## Verificando nossa transação financiada + +Parece mágica, então nas primeiras vezes que usarmos o ```fundrawtransaction```, provavelmente vamos querer verificá-la. + +Vamos executar o comando ```decoderawtransaction``` para mostrar que a transação bruta agora está disposta corretamente, usando um ou mais dos nossos UTXOs e enviando fundos excedentes de volta para um endereço de alteração: +``` +$ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 +{ + "txid": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", + "hash": "b3b4c2057dbfbef6690e975ede92fde805ddea13c730f58401939a52c9ac1b99", + "version": 2, + "size": 116, + "vsize": 116, + "weight": 464, + "locktime": 0, + "vin": [ + { + "txid": "eb84c5008038d760805d4d9644ace67849542864220cb2685a1ea2c64176b82d", + "vout": 1, + "scriptSig": { + "asm": "", + "hex": "" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.00020000, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 e7c1345fc8f87c68170b3aa798a956c2fe6a9eff OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi" + ] + } + }, + { + "value": 0.00007800, + "n": 1, + "scriptPubKey": { + "asm": "0 a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "hex": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r" + ] + } + } + ] +} +``` +Uma coisa de interesse aqui é o endereço de troco, que é o segundo ```vout```. Observe que é um endereço ```tb1```, o que significa que é do tipo Bech32. Quando demos ao Bitcoin Core a capacidade total de gerenciar as alterações, ele o fez usando o tipo de endereço padrão, Bech32, e funcionou bem. É por isso que nossa mudança para endereços SegWit na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md) realmente não é um grande negócio, mas existem algumas dicas para uso mais amplo, sobre as quais falaremos lá. + +Embora tenhamos visto a taxa na saída no ```fundrawtransaction```, ela não pode ser visível aqui. No entanto, podemos verificar isso com o script JQ ```txfee-calc.sh``` criado na sessão [Prefácio: Usando o JQ](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master /04_2__Interlude_Using_JQ.md): +``` +$ ~/txfee-calc.sh $rawtxhex3 +.000222 +``` +Finalmente, podemos usar o ```getaddressinfo``` para ver se o endereço de alteração gerado realmente nos pertence: +``` +$ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r +{ + "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "ismine": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", + "iswatchonly": false, + "isscript": false, + "iswitness": true, + "witness_version": 0, + "witness_program": "a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "pubkey": "038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5", + "ischange": true, + "timestamp": 1592335137, + "hdkeypath": "m/0'/1'/10'", + "hdseedid": "fdea8e2630f00d29a9d6ff2af7bf5b358d061078", + "hdmasterfingerprint": "d6043800", + "labels": [ + ] +} +``` +Observe os conteúdo do `ismine`. + +## Enviando a transação financiada + +Neste ponto, podemos assinar e enviar a transação normalmente. +``` +$ signedtx3=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex3 | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx3 +8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa +``` +Em alguns minutos, teremos o nosso troco de volta: +``` +$ bitcoin-cli listunspent +[ + { + "txid": "8b9dd66c999966462a3d88d6ac9405d09e2aa409c0aa830bdd08dbcbd34a36fa", + "vout": 1, + "address": "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + "scriptPubKey": "0014a782f4c6e1e75a5b24f3d675d6f11b5ebf3b2142", + "amount": 0.00007800, + "confirmations": 1, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/1'/10']038a2702938e548eaec28feb92c7e4722042cfd1ea16bec9fc274640dc5be05ec5)#zpv26nar", + "safe": true + } +] +``` + +## Resumo do Enviando bitcoins usando transações brutas automatizadas + +Se formos enviar fundos usando transações brutas, então o ```fundrawtransaction``` oferece uma boa alternativa onde taxas, entradas e saídas são calculadas para nós, para que não percamos acidentalmente muito dinheiro. + +> :fire: ***Qual é o poder de enviar moedas com transações brutas automatizadas?*** +> _As vantagens._ Proporciona um bom meio de campo. Se estamos enviando fundos manualmente e o ```sendtoaddress``` não oferece controle suficiente por qualquer motivo, podemos obter algumas das vantagens das transações brutas sem os perigos dela. Essa metodologia deve ser usada sempre que possível se estivermos enviando transações brutas manualmente. +> _As desvantagens._ É uma meio termo. Embora existam algumas opções adicionais no ```fundrawtransaction``` que não foram mencionadas aqui, nosso controle ainda é limitado. Provavelmente, nunca desejaríamos usar esse método se formos escrever um programa cujo objetivo é saber exatamente o que está acontecendo. + +## O que vem depois? + +Vamos concluir o capítulo "Enviando transações no Bitcoin" com a sessão [§4.6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md). \ No newline at end of file diff --git a/pt/04_6_Creating_a_Segwit_Transaction.md b/pt/04_6_Creating_a_Segwit_Transaction.md new file mode 100644 index 0000000..1064409 --- /dev/null +++ b/pt/04_6_Creating_a_Segwit_Transaction.md @@ -0,0 +1,288 @@ +# 4.6: Criando uma transação do tipo SegWit + +> :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. + +Era uma vez, nos céus do Bitcoin, uma guerra entre os tamanhos de blocos eclodiu. As taxas disparavam e os usuários estavam preocupados se o Bitcoin podia realmente escalar. Os desenvolvedores do Bitcoin Core relutaram em simplesmente aumentar o tamanho do bloco, mas chegaram a um acordo: Fizeram o SegWit, que significa Segregated Witness. A Segregated Witness é uma maneira elegante de dizer "Assinatura Separada". Ele cria novos tipos de transações que removem assinaturas no final da transação. Ao combinar isso com o aumento dos tamanhos de bloco que são visíveis apenas para nós atualizados, o SegWit resolveu os problemas de dimensionamento do Bitcoin na época e também resolveu um bug de maleabilidade desagradável, tornando o dimensionamento ainda melhor para protocolos de segunda camada, como a Lightning Network. + +A sacada? O SegWit usa endereços diferentes, alguns dos quais são compatíveis com nodes mais antigos e outros não. + +> :warning: **AVISO DE VERSÃO:** O SegWit foi introduzido no BitCoin 0.16.0, que foi descrito na época como tendo "suporte total". Dito isso, havia algumas falhas na integração com o ```bitcoin-cli``` na época, que impediam a assinatura de funcionar corretamente em novos endereços P2SH-SegWit. O endereço Bech32, não compatível com versões anteriores, também foi introduzido no Bitcoin 0.16.0 e se tornou o tipo de endereço padrão no Bitcoin 0.19.0. Toda essa funcionalidade deve estar totalmente funcional em relação às funções ```bitcoin-cli``` (e, portanto, devem funcionar completamente neste tutorial). + +> O problema está em interagir com o mundo. Todos devem ser capazes de enviar para um endereço P2SH-SegWit porque foi construído propositadamente para suportar compatibilidade com as versões anteriores, envolvendo a funcionalidade SegWit em um Script Bitcoin. O mesmo não é verdade para endereços Bech32: Se alguém nos disser que não pode enviar para o nosso endereço Bech32 precisaremos gerar um endereço ```legado``` ou P2SH-SegWit para fazer a transação. (Muitos sites, principalmente as exchanges, também não podem gerar ou receber em endereços SegWit, particularmente endereços Bech32, mas isso é um problema totalmente diferente e não afeta o uso delas). + +## Compreendendo uma transação SegWit + +Em transações clássicas, as informações de assinatura (witness) eram armazenadas no meio da transação, enquanto nas transações SegWit, elas ficavam na parte inferior. Isso anda de mãos dadas com os aumentos de tamanho do bloco que foram introduzidos na atualização do SegWit. O tamanho do bloco foi aumentado de 1 mega para um valor variável com base em quantas transações SegWit estão em um bloco, começando em 1 mega (sem transações SegWit) e podendo chegar a 4 megas (caso todas as transações sejam SegWit). Este tamanho variável foi criado para acomodar os nodes legados, de forma que tudo permaneça compatível com as versões anteriores. Se um node clássico vê uma transação SegWit, ele joga fora as informações da witness (resultando em um bloco de tamanho menor, abaixo do antigo limite de 1 mega), enquanto se um novo node vê uma transação SegWit, ele mantém as informações da witness (resultando em um maior tamanho de bloco, até o novo limite de 4 megas). + +Portanto, acabamos de responder o quê são e como funcionam as transações SegWit. Não que precisemos saber disso para usá-las. A maioria das transações na rede Bitcoin são SegWit. Elas são aquilo que iremos utilizar nativamente para as transações e recebimentos de bitcoins. Os detalhes não são mais relevantes à partir deste ponto, tanto quanto não são mais relevantes como o Bitcoin funciona. + +## Criando um endereço SegWit + +Criamos um endereço SegWit da mesma maneira que qualquer outro endereço, com os comandos ```getnewaddress``` e ```getrawchangeaddress```. + +Se precisarmos criar um endereço para alguém que não pode enviar para os endereços Bech32 mais recentes, podemos usar um endereço ```p2sh-segwit```: +``` +$ bitcoin-cli -named getnewaddress address_type=p2sh-segwit +2N5h2r4karVqN7uFtpcn8xnA3t5cbpszgyN +``` +Se conseguirmos ver um endereço com o prefixo "2" significa que fizemos tudo certo. + +> :link: **TESTNET vs MAINNET:** "3" no caso da mainnet. + +No entanto, se a pessoa com quem estamos interagindo tem um node com uma versão mais nova, ela poderá enviar para um endereço Bech32, que criamos usando os comandos da maneira padrão: +``` +$ bitcoin-cli getnewaddress +tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 +``` +Como já vimos, os endereços de troco gerados a partir do ```bitcoin-cli``` interagem bem com os endereços Bech32, então não há motivo nenhum usar o sinalizador ```legacy``` lá também: +``` +$ bitcoin-cli getrawchangeaddress +tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff +``` + +Aqui, podemos observar que o prefixo "tb1" exclusivo denota que o endereço é um Bech32. + +> :link: ** TESTNET vs MAINNET: ** "bc1" no caso da mainnet. + +O Bitcoin-cli não se importa com o tipo de endereço que estamos utilizando. Podemos executar um comando como ```listaddressgroupings``` que ele irá misturar os endereços livremente não importando os tipos: +``` +$ bitcoin-cli listaddressgroupings +[ + [ + [ + "mfsiRhxbQxcD7HLS4PiAim99oeGyb9QY7m", + 0.01000000, + "" + ] + ], + [ + [ + "mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE", + 0.00000000, + "" + ], + [ + "tb1q6dak4e9fz77vsulk89t5z92l2e0zm37yvre4gt", + 0.00000000 + ] + ], + [ + [ + "mjehC2KHzXcBDcwTd4LhZ2GzyzrZ3Kd3ff", + 0.00022000, + "" + ] + ], + [ + [ + "mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h", + 0.00000000 + ], + [ + "mqjrdY5raxKzXQf5t2VvVvzhvFAgersu9B", + 0.00000000 + ], + [ + "mwJL7cRiW2bUnY81r1thSu3D4jtMmwyU6d", + 0.00000000, + "" + ], + [ + "tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r", + 0.00007800 + ] + ], + [ + [ + "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", + 0.01000000, + "" + ] + ], + [ + [ + "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", + 0.01000000, + "" + ] + ] +] +``` + +## Enviando uma transação SegWit no modo easy + +Então, como enviamos uma transação Segwit? Exatamente como qualquer outra transação. Não importa se o UTXO é SegWit, o endereço é SegWit ou alguma combinação dos dois. Podemos ter a certeza que o ```bitcoin-cli``` irá fazer a coisa certa. Embora possamos perceber algumas diferenças nos endereços, eles não importam para interagir com as coisas no nível do ```bitcoin-cli``` ou do RPC. (E esta é uma das vantagens de usar a linha de comando e a interface do RPC, conforme sugerido neste tutorial: Os especialistas já fizeram o trabalho duro para nós, incluindo coisas como enviar para endereços legados e Bech32. Acabamos usando essa funcionalidade para nosso próprio benefício). + +Aqui está um exemplo de um envio para um endereço SegWit, no modo easy: +``` +$ bitcoin-cli sendtoaddress tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005 +854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42 +``` +Se olhar para a nossa transação, podemos ver o uso do endereço Bech32: +``` +$ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42" verbose=true +{ + "amount": -0.00500000, + "fee": -0.00036600, + "confirmations": 0, + "trusted": true, + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "walletconflicts": [ + ], + "time": 1592948795, + "timereceived": 1592948795, + "bip125-replaceable": "no", + "details": [ + { + "address": "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", + "category": "send", + "amount": -0.00500000, + "vout": 1, + "fee": -0.00036600, + "abandoned": false + } + ], + "hex": "0200000002114d5a4c3b847bc796b2dc166ca7120607b874aa6904d4a43dd5f9e0ea79d4ba010000006a47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042dfeffffffa71321e81ef039af490251379143f7247ad91613c26c8f3e3404184218361733000000006a47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7efeffffff026854160000000000160014d591091b8074a2375ed9985a9c4b18efecfd416520a1070000000000160014751e76e8199196d454941c45d1b3a323f1433bd6c60e1b00", + "decoded": { + "txid": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "hash": "854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42", + "version": 2, + "size": 366, + "vsize": 366, + "weight": 1464, + "locktime": 1773254, + "vin": [ + { + "txid": "bad479eae0f9d53da4d40469aa74b8070612a76c16dcb296c77b843b4c5a4d11", + "vout": 1, + "scriptSig": { + "asm": "304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7[ALL] 03ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d", + "hex": "47304402200a3cc08b9778e7b616340d4cf7841180321d2fa019e43f25e7f710d9a628b55c02200541fc200a07f2eb073ad8554357777d5f1364c5a96afe5e77c6185d66a40fa7012103ee18c598bafc5fbea72d345329803a40ebfcf34014d0e96aac4f504d54e7042d" + }, + "sequence": 4294967294 + }, + { + "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", + "vout": 0, + "scriptSig": { + "asm": "304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a316[ALL] 0339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e", + "hex": "47304402200dd80206b57beb5fa38a3c3578f4b0e40d56d4079116fd2a6fe28e5b8ece72310220298a8c3a1193ea805b27608ff67a2d8b01e347e33a4222edfba499bb1b64a31601210339c001b00dd607eeafd4c117cfcf86be8efbb0ca0a33700cffc0ae0c6ee69d7e" + }, + "sequence": 4294967294 + } + ], + "vout": [ + { + "value": 0.01463400, + "n": 0, + "scriptPubKey": { + "asm": "0 d591091b8074a2375ed9985a9c4b18efecfd4165", + "hex": "0014d591091b8074a2375ed9985a9c4b18efecfd4165", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1q6kgsjxuqwj3rwhkenpdfcjccalk06st9z0k0kh" + ] + } + }, + { + "value": 0.00500000, + "n": 1, + "scriptPubKey": { + "asm": "0 751e76e8199196d454941c45d1b3a323f1433bd6", + "hex": "0014751e76e8199196d454941c45d1b3a323f1433bd6", + "reqSigs": 1, + "type": "witness_v0_keyhash", + "addresses": [ + "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx" + ] + } + } + ] + } +} +``` +Na verdade, ambos os ```vouts``` usam endereços Bech32: O nosso destinatário e o endereço de troco gerado automaticamente. + +Mas quando retrocedemos nosso ```vin```, descobrimos que veio de um endereço legado. Isso porque não importa: +``` +$ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7" +{ + "amount": 0.01000000, + "confirmations": 43, + "blockhash": "00000000000000e2365d2f814d1774b063d9a04356f482010cdfdd537b1a24bb", + "blockheight": 1773212, + "blockindex": 103, + "blocktime": 1592937103, + "txid": "33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7", + "walletconflicts": [ + ], + "time": 1592936845, + "timereceived": 1592936845, + "bip125-replaceable": "no", + "details": [ + { + "address": "mpVLL7iqPr4d7BJkEG54mcdm7WmrAhaW6q", + "category": "receive", + "amount": 0.01000000, + "label": "", + "vout": 0 + } + ], + "hex": "020000000001016a66efa334f06e2c54963e48d049a35d7a1bda44633b7464621cae302f35174a0100000017160014f17b16c6404e85165af6f123173e0705ba31ec25feffffff0240420f00000000001976a914626ab1ca41d98f597d18d1ff8151e31a40d4967288acd2125d000000000017a914d5e76abfe5362704ff6bbb000db9cdfa43cd2881870247304402203b3ba83f51c1895b5f639e9bfc40124715e2495ef2c79d4e49c0f8f70fbf2feb02203d50710abe3cf37df4d2a73680dadf3cecbe4f2b5d0b276dbe7711d0c2fa971a012102e64f83ee1c6548bcf44cb965ffdb803f30224459bd2e57a5df97cb41ba476b119b0e1b00" +} +``` + +## Enviando uma transação SegWit o modo hard + +Da mesma forma, podemos financiar uma transação com um endereço Bech32, sem nenhuma diferença em relação às técnicas que aprendemos até agora. Aqui está uma maneira exata de fazer isso com uma transação bruta completa: +``` +$ changeaddress=$(bitcoin-cli getrawchangeaddress) +$ echo $changeaddress +tb1q4xje3mx9xn7f8khv7p69ekfn0q72kfs8x3ay4j +$ bitcoin-cli listunspent +[ +... + { + "txid": "003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452", + "vout": 0, + "address": "tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6", + "label": "", + "scriptPubKey": "0014a226e1dfd08537b02de04f667a49bd46f9b9f578", + "amount": 0.01000000, + "confirmations": 5, + "spendable": true, + "solvable": true, + "desc": "wpkh([d6043800/0'/0'/5']0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640)#hd66hknp", + "safe": true + } +] +$ recipient=tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx +$ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') +$ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') +$ echo $utxo_txid $utxo_vout +003bfdca5578c0045a76768281f05d5e6f57774be399a76f387e2a0e99e4e452 0 +$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.002, "'$changeaddress'": 0.007 }''') +$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex | jq -r '.hex') +$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx +e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c +``` +Tudo funciona exatamente da mesma forma que outros tipos de transações! + +### Reconhecendo o novo descritor + +Se olharmos o campo ```desc```, notaremos que o endereço SegWit tem um descritor de estilo diferente daqueles encontrados na sessão [§3.5: Entendendo o descritor](03_5_Understanding_the_Descriptor.md). Um descritor legado descrito nessa sessão se parecia com algo assim: `pkh ([d6043800 / 0 '/ 0' / 18 '] 03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388) # 4ahsl9pk`. Nosso novo descritor SegWit se parece mais com isso: `wpkh ([d6043800 / 0 '/ 0' / 5 '] 0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640) # hd66hknp" `. + +A grande diferença que precisamos notar é que a função mudou. Anteriormente, era ```pkh```, que é um endereço padrão de chave pública com hash P2PKH. Ao invés disso, o endereço SegWit é ```wpkh```, o que significa que é um endereço SegWit P2WPKH nativo. Isso dá destaque ao :fire: ***poder dos descritores***. Eles descrevem como criar um endereço a partir de uma chave ou outra informação, com as funções definindo de forma inequívoca como fazer o endereço com base no tipo de cada endereço. + +## Resumo do Criando uma transação do tipo SegWit + +Realmente não há complexidade para criar transações SegWit. Internamente, elas são estruturadas de forma diferente das transações legadas, mas na linha de comando não existe diferença: Apesar usamos um endereço com um prefixo diferente. A única coisa a ser observada é que algumas pessoas podem não conseguir enviar para um endereço Bech32 se estiverem usando um software obsoleto. + +> :fire: ***Qual é o poder de criar transações usando o SegWit?*** +> _As vantagens._ As transações do SegWit são menores e, portanto, serão mais baratas de serem enviadas do que as transações legadas devido às taxas mais baixas. O Bech32 diminui essa vantagem e também cria endereços que são mais difíceis de errar durante a transcrição, e isso é muito importante, visto que o erro do usuário é uma das maneiras mais prováveis de terem seus bitcoins perdidos. +> _As desvantagens._ Os endereços SegWit não tem suporte em nodes do Bitcoin obsoleto. Em particular, as pessoas podem não conseguir enviar para o nosso endereço Bech32. + +## O que vem depois? + +Vamos avançar mais um pouco no "bitcoin-cli" com o [Capítulo 5: Controlando as transações do Bitcoin](05_0_Controlling_Bitcoin_Transactions.md). \ No newline at end of file From 6ba639af994b6e4425cff8a7a0ecfeb2e5520f0d Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 11:56:27 -0300 Subject: [PATCH 28/50] =?UTF-8?q?Revis=C3=A3o=20da=20introdu=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Teste de revisão. --- pt/03_0_Understanding_Your_Bitcoin_Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pt/03_0_Understanding_Your_Bitcoin_Setup.md b/pt/03_0_Understanding_Your_Bitcoin_Setup.md index 865b693..275adef 100644 --- a/pt/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/pt/03_0_Understanding_Your_Bitcoin_Setup.md @@ -1,4 +1,4 @@ -# Capítulo três: Compreendendo a configuração do seu node Bitcoin +# Capítulo 3: Compreendendo a configuração do node Bitcoin Agora que você está pronto para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que você entenda a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. From 240f7ad010c51094b39a90d73099ba706b9a8ae3 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 11:57:57 -0300 Subject: [PATCH 29/50] =?UTF-8?q?Revert=20"Revis=C3=A3o=20da=20introdu?= =?UTF-8?q?=C3=A7=C3=A3o"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 6ba639af994b6e4425cff8a7a0ecfeb2e5520f0d. --- pt/03_0_Understanding_Your_Bitcoin_Setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pt/03_0_Understanding_Your_Bitcoin_Setup.md b/pt/03_0_Understanding_Your_Bitcoin_Setup.md index 275adef..865b693 100644 --- a/pt/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/pt/03_0_Understanding_Your_Bitcoin_Setup.md @@ -1,4 +1,4 @@ -# Capítulo 3: Compreendendo a configuração do node Bitcoin +# Capítulo três: Compreendendo a configuração do seu node Bitcoin Agora que você está pronto para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que você entenda a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. From b1529ebb70898a11a23d6c1b1dcc28144c257f2b Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 12:00:32 -0300 Subject: [PATCH 30/50] Chapter 3.0 Reviewed --- pt/03_0_Understanding_Your_Bitcoin_Setup.md | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pt/03_0_Understanding_Your_Bitcoin_Setup.md b/pt/03_0_Understanding_Your_Bitcoin_Setup.md index 865b693..5bea404 100644 --- a/pt/03_0_Understanding_Your_Bitcoin_Setup.md +++ b/pt/03_0_Understanding_Your_Bitcoin_Setup.md @@ -1,27 +1,27 @@ -# Capítulo três: Compreendendo a configuração do seu node Bitcoin +# Capítulo 3: Compreendendo a configuração do node Bitcoin -Agora que você está pronto para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que você entenda a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. +Agora que estamos prontos para começar a trabalhar com a interface de linha de comando `bitcoin-cli`. Mas isso requer primeiro que entendamos a configuração do Bitcoin e os recursos da carteira, que é o que será explicado neste capítulo. -Neste e nos próximos capítulos, presumimos que você tenha uma VPS com Bitcoin instalado, executando `bitcoind`. Também presumimos que você está conectado à testnet, permitindo o acesso a bitcoins sem usar fundos reais. Você pode fazer isso com Bitcoin Standup em linode.com, por [2.1: Configurando um Bitcoin-Core no VPS c Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou por outros métodos, por [2.2: Configurando um node Bitcoin Core por outros métodos](02_2_Setting_Up_Bitcoin_Core_Other.md). +Neste e nos próximos capítulos, presumimos que uma VPS com Bitcoin instalado esteja sendo utilizada, e que iremos executar o `bitcoind`. Também presumimos que estamos conectados à testnet, permitindo o acesso a bitcoins sem usar fundos reais. Podemos fazer isso com Bitcoin Standup em linode.com, como vimos na sessão [2.1: Configurando um Bitcoin-Core no VPS c Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md), ou usando os demais métodos, descritos na sessão [2.2: Configurando um node Bitcoin Core por outros métodos](02_2_Setting_Up_Bitcoin_Core_Other.md). ## Objetivos deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - * Demonstrar que o node Bitcoin está instalado e atualizado - * Criar um endereço para receber fundos de Bitcoin - * Usar os comandos básicos da carteira - * Criar um endereço a partir de um descritor + * Demonstrar que o node Bitcoin está instalado e atualizado; + * Criar um endereço para receber bitcoins; + * Usar os comandos básicos da carteira; + * Criar um endereço a partir de um descritor. -Os objetivos de apoio incluem a capacidade de: +Os objetivos secundários incluem a capacidade de: - * Compreender o layout básico do arquivo Bitcoin - * Usar comandos informativos básicos - * Entender o que é um endereço Bitcoin - * Entender o que é uma carteira - * Entender como importar endereços + * Compreender o layout básico do arquivo Bitcoin; + * Usar comandos informativos básicos; + * Entender o que é um endereço Bitcoin; + * Entender o que é uma carteira; + * Entender como importar endereços. -## Índice +## Tabela de Conteúdo * [Seção Um: Verificando a configuração do seu node Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) * [Seção Dois: conhecendo a configuração do seu node Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) From 2a062b6a938d6fb86dc94856bf7b29f139df9299 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 12:30:28 -0300 Subject: [PATCH 31/50] Session 03.1 reviewed --- pt/03_1_Verifying_Your_Bitcoin_Setup.md | 59 +++++++++++++------------ 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/pt/03_1_Verifying_Your_Bitcoin_Setup.md b/pt/03_1_Verifying_Your_Bitcoin_Setup.md index 2997ef3..528af90 100644 --- a/pt/03_1_Verifying_Your_Bitcoin_Setup.md +++ b/pt/03_1_Verifying_Your_Bitcoin_Setup.md @@ -1,12 +1,13 @@ -# 3.1: Verificando a configuração do seu node Bitcoin -Antes de começar a brincar com Bitcoin, você deve se certificar de que tudo está configurado corretamente. +# 3.1: Verificando a configuração do node Bitcoin -## Crie seus aliases +Antes de começarmos a brincar com Bitcoin, devemos nos certificar de que tudo está configurado corretamente. -Sugerimos a criação de alguns aliases para facilitar o uso do Bitcoin +## Crie os aliases -Você pode fazer isso colocando-os em seu `.bash_profile`,` .bashrc` ou `.profile`. +Sugerimos a criação de alguns aliases (um tipo de atalho) para facilitar o uso do Bitcoin. + +Podemos fazer isso colocando-os em nosso `.bash_profile`, `.bashrc` ou no `.profile`. ``` cat >> ~/.bash_profile < :book: ***O que é a altura do bloco?*** A altura do bloco é a distância que um bloco particular está do bloco de gênese. A altura do bloco atual é a altura do bloco mais recente adicionado a um blockchain. +> :book: ***O que é a altura do bloco?*** A altura do bloco é a distância que um bloco particular está do bloco de gênese. A altura do bloco atual é a altura do bloco mais recente adicionado a blockchain. -Você pode fazer isso olhando para um explorador, como [Mempool Space Explorer](https://mempool.space/pt/testnet). O número mais recente corresponde ao `getblockcount`? Se sim, você está atualizado. +Podemos fazer isso olhando um explorador, como o [Mempool Space Explorer](https://mempool.space/pt/testnet). É o número mais recente corresponde ao `getblockcount`? Se sim, nossa blockchain está atualizada. -Se você quiser que um alias veja tudo de uma vez, o seguinte funciona atualmente para Testnet, mas pode desaparecer em algum momento no futuro: +Se quisermos que um alias veja tudo de uma vez, o código abaixo funciona normalmente no Testnet, mas pode desaparecer em algum momento no futuro: ``` $ cat >> ~/.bash_profile << EOF alias btcblock="echo \\\`bitcoin-cli getblockcount 2>&1\\\`/\\\`wget -O - https://blockstream.info/testnet/api/blocks/tip/height 2> /dev/null | cut -d : -f2 | rev | cut -c 1- | rev\\\`" @@ -54,25 +55,25 @@ $ btcblock 1804372/1804372 ``` -> :link: **TESTNET vs MAINNET:** Lembre-se de que este tutorial geralmente assume que você está usando testnet. Se você estiver usando a mainnet, pode recuperar a altura do bloco atual com: `wget -O - https://mempool.space/testnet/api/blocks/tip/height 2> /dev/ null`. Você pode substituir a última metade do alias `btblock` (após `/`) por isso. +> :link: **TESTNET vs MAINNET:** Lembre-se de que este tutorial geralmente assume que estamos usando a Testnet. Se estivermos usando a mainnet, podemos recuperar a altura do bloco atual usando a seguinte linha de comando: `wget -O - https://mempool.space/testnet/api/blocks/tip/height 2> /dev/ null`. Podemos substituir a última metade do alias `btblock` (após `/`) por isso. -Se você não está atualizado, mas seu `getblockcount` está aumentando, não há problema. O tempo total de download pode levar de uma hora a várias horas, dependendo da configuração. +Se a nossa blockchain não estiver atualizada, mas nosso `getblockcount` estiver aumentando, não há problema. O tempo total de download pode levar de uma a várias horas, dependendo da configuração. -## Opcional: Conheça os tipos de servidores +## Opcional: Conhecendo os tipos de servidores -> **TESTNET vs MAINNET:** Ao configurar seu node Bitcoin, você escolhe criá-lo como um Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração de rede de teste, vale a pena entender como você pode acessar e usar os outros tipos de configuração - mesmo todos na mesma máquina! Mas, se você for um usuário iniciante, pule isso, pois não é necessário para uma configuração básica. +> **TESTNET vs MAINNET:** Ao configurar o node Bitcoin, precisamos escolher se vamos criá-lo como sendo um Mainnet, Testnet ou Regtest. Embora este documento presuma uma configuração de Testnet, vale a pena entender como podemos acessar e usar os outros tipos de configuração, inclusive, como ter todos na mesma máquina! Mas, se formos iniciantes, podemos pular isso, pois não é necessário para uma configuração básica. -O tipo de configuração é controlado principalmente por meio do arquivo `~/.bitcoin/bitcoin.conf`. Se você estiver executando o testnet, provavelmente contém esta linha: +O tipo de configuração é controlado principalmente por meio do arquivo `~/.bitcoin/bitcoin.conf`. Se estivermos executando o Testnet, provavelmente teremos a seguinte linha: ``` testnet=1 ``` -Se você estiver executando o regtest, provavelmente contém esta linha: +Se estivermos executando a Regtest, provavelmente teremos essa linha: ``` regtest=1 ``` -No entanto, se você deseja executar vários tipos diferentes de nós simultaneamente, deve deixar o sinalizador testnet (ou regtest) fora de seu arquivo de configuração. Você pode então escolher se está usando mainnet, testnet ou regtest toda vez que executar bitcoind ou bitcoin-cli. +No entanto, se desejarmos executar vários tipos diferentes de nós simultaneamente, devemos deixar o um sinalizador Testnet (ou Regtest) fora do nosso arquivo de configuração. Podemos então escolher se estamos usando a Mainnet, Testnet ou Regtest toda vez que executarmos o bitcoind ou o bitcoin-cli. -Aqui está um conjunto de aliases que tornariam isso mais fácil, criando um alias específico para iniciar e parar o bitcoind, para ir para o diretório bitcoin e para executar bitcoin-cli, para cada mainnet (que não tem sinalizadores extras), o testnet (que é -testnet), ou seu regtest (que é -regtest). +Aqui está um conjunto de aliases que tornariam isso mais fácil, criando um alias específico para iniciar e parar o bitcoind, para ir para o diretório bitcoin e para executar o bitcoin-cli, na Mainnet (que não tem sinalizadores extras), no Testnet (que é -testnet), ou no nosso Regtest (que é -regtest). ``` cat >> ~/.bash_profile < Date: Sat, 26 Jun 2021 12:45:21 -0300 Subject: [PATCH 32/50] Session 3.2 reviewed --- pt/03_2_Knowing_Your_Bitcoin_Setup.md | 51 ++++++++++++++------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/pt/03_2_Knowing_Your_Bitcoin_Setup.md b/pt/03_2_Knowing_Your_Bitcoin_Setup.md index ba064c8..a1123a7 100644 --- a/pt/03_2_Knowing_Your_Bitcoin_Setup.md +++ b/pt/03_2_Knowing_Your_Bitcoin_Setup.md @@ -1,31 +1,32 @@ -# 3.2: Conhecendo a configuração do seu node Bitcoin -Antes de começar o jogo com Bitcoin, você pode sempre querer entender melhor sua configuração. +# 3.2: Conhecendo a configuração do node Bitcoin -## Conhecendo o seu diretório Bitcoin +Antes de começarmos a brincar com Bitcoin, é sempre bom entender melhor nossa configuração. -Para começar, você deve entender onde tudo é guardado: o diretório `~/.bitcoin`. +## Conhecendo o diretório do Bitcoin -O diretório principal contém apenas seu arquivo de configuração e o diretório testnet: +Para começar, devemos entender onde tudo está guardado: O diretório `~/.bitcoin`. + +O diretório principal contém apenas nosso arquivo de configuração e o diretório Testnet: ``` $ ls ~/.bitcoin bitcoin.conf testnet3 ``` -Os guias de configuração em [Capítulo dois: Criando um VPS Bitcoin-Core](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) estabelecem um arquivo de configuração padronizado. [3.1: Verificando sua configuração do seu node Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) Sugeri como alterá-lo para oferecer suporte a configurações mais avançadas. Se você estiver interessado em aprender ainda mais sobre o arquivo de configuração, você pode consultar [Jameson Lopp's Bitcoin Core gerador de configuração](https://jlopp.github.io/bitcoin-core-config-generator/). +Os guias de configuração no [Capítulo dois: Criando um VPS Bitcoin-Core](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) estabelecem um arquivo de configuração padronizado. Na sessão [3.1: Verificando a configuração do node Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) sugerimos como alterá-la para oferecer suporte a configurações mais avançadas. Se estivermos interessados em aprender ainda mais sobre o arquivo de configuração, podemos consultar o [Gerador de Configuração do Bitcoin Core escrito por Jameson Lopp's](https://jlopp.github.io/bitcoin-core-config-generator/). -Voltando para o diretório `~/.bitcoin`, você descobrirá que o diretório testnet3 contém todos os elementos: +Voltando para o diretório `~/.bitcoin`, iremos descobrir que o diretório testnet3 contém todos os elementos: ``` $ ls ~/.bitcoin/testnet3 -banlist.dat blocks debug.log mempool.dat peers.dat -bitcoind.pid chainstate fee_estimates.dat onion_private_key wallets +banlist.dat blocks debug.log mempool.dat peers.dat +bitcoind.pid chainstate fee_estimates.dat onion_private_key wallets ``` -Você não deve mexer com a maioria desses arquivos e diretórios - particularmente não com os diretórios `blocks` e` chainstate`, que contêm todos os dados do blockchain, e as informações em seu diretório `wallets`, que contém sua carteira pessoal. No entanto, preste atenção ao arquivo `debug.log`, que você deve consultar se tiver problemas com sua configuração. +Não deve mexer com a maioria desses arquivos e diretórios, particularmente os diretórios `blocks` e `chainstate` não devem ser tocados, pois contêm todos os dados da blockchain, e as informações do nosso diretório `wallets`, que contém nossa carteira. No entanto, podemos prestar atenção ao arquivo `debug.log`, que devemos consultar se começarmos a ter problemas com nossa configuração. -> :link: **TESTNET vs MAINNET:** Se você estiver usando mainnet, então _tudo_ será colocado no diretório principal `~/.bitcoin`. Então se você estiver usando mainnet, testnet e regtest, você verá que `~/.bitcoin` contém seu arquivo de configuração e seus dados mainnet, o diretório` ~/.bitcoin/testnet3` contém seus dados testnet, e o diretório `~/.bitcoin/regtest` contém seus dados de regtest. +> :link: **TESTNET vs MAINNET:** Se estivermos usando a Mainnet, então _tudo_ será colocado no diretório principal `~/.bitcoin`. Então se estivermos usando a Mainnet, Testnet e a Regtest, veremos que o `~/.bitcoin` contém nosso arquivo de configuração e nossos dados da mainnet, o diretório `~/.bitcoin/testnet3` contém nossos dados da Testnet, e o diretório `~/.bitcoin/regtest` contém os dados do regtest. -## Conheça os comandos do Bitcoin-cli +## Conhecendo os comandos do Bitcoin-cli -A maior parte do seu trabalho inicial será feito com o comando `bitcoin-cli`, que oferece uma interface fácil para o `bitcoind`. Se você quiser mais informações sobre seu uso, basta executá-lo com o argumento `help`. Sem nenhum outro argumento, ele mostrara todos os comandos possíveis: +A maior parte do nosso trabalho inicial será feito com o comando `bitcoin-cli`, que oferece uma interface simples para o `bitcoind`. Se quisermos mais informações sobre como utilizá-lo, basta executá-lo com o argumento `help`. Sem nenhum outro argumento, ele mostrara todos os possíveis comandos: ``` $ bitcoin-cli help == Blockchain == @@ -178,7 +179,7 @@ walletprocesspsbt "psbt" ( sign "sighashtype" bip32derivs ) == Zmq == getzmqnotifications ``` -Você também pode digitar `bitcoin-cli help [command]` para obter informações ainda mais detalhadas sobre aquele comando. Por exemplo: +Podemos digitar também `bitcoin-cli help [command]` para obtermos informações ainda mais detalhadas sobre aquele comando. Por exemplo: ``` $ bitcoin-cli help getmininginfo ... @@ -199,13 +200,13 @@ Examples: > bitcoin-cli getmininginfo > curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ ``` -> :book: ***What is RPC?*** `bitcoin-cli` is just a handy interface that lets you send commands to the `bitcoind`. More specifically, it's an interface that lets you send RPC (or Remote Procedure Protocol) commands to the `bitcoind`. Often, the `bitcoin-cli` command and the RPC command have identical names and interfaces, but some `bitcoin-cli` commands instead provide shortcuts for more complex RPC requests. Generally, the `bitcoin-cli` interface is much cleaner and simpler than trying to send RPC commands by hand, using `curl` or some other method. However, it also has limitations as to what you can ultimately do. +> :book: ***O que é o RPC?*** O`bitcoin-cli` é apenas uma interface útil que permite enviar comandos para o`bitcoind`. Mais especificamente, é uma interface que permite enviar comandos RPC (Remote Procedure Protocol ou, protocolo de procedimento remoto, no português) para o `bitcoind`. Frequentemente, o comando `bitcoin-cli` e o comando RPC possuem nomes e interfaces idênticos, mas alguns comandos no `bitcoin-cli` fornecem atalhos para solicitações RPC mais complexas. Geralmente, a interface `bitcoin-cli` é muito mais limpa e simples do que tentar enviar comandos RPC manualmente, usando `curl` ou algum outro método. No entanto, ele também tem limitações quanto ao que podemos fazer. -## Opcional: Conheça as informações do seu node Bitcoin +## Opcional: Conhecendo as informações do node Bitcoin -Uma variedade de comandos bitcoin-cli podem fornecer informações adicionais sobre seus node Bitcoin. Os mais gerais são: +Uma variedade de comandos bitcoin-cli podem fornecer informações adicionais sobre nossos node Bitcoin. Os mais comuns são: -`bitcoin-cli -getinfo` retorna informações diferentes do RPC +`bitcoin-cli -getinfo` retorna informações do RPCs mais fáceis de serem lidas. ```diff $ bitcoin-cli -getinfo @@ -233,7 +234,7 @@ Transaction fee rate (-paytxfee) (BTC/kvB): 0.00000000 ``` -Outros comandos para obter informações sobre blockchain, mineração, rede, carteira etc. +Abaixo apresentamos outros comandos para obter informações sobre blockchain, mineração, rede, carteira etc. ``` $ bitcoin-cli getblockchaininfo @@ -242,7 +243,7 @@ $ bitcoin-cli getnetworkinfo $ bitcoin-cli getnettotals $ bitcoin-cli getwalletinfo ``` -Por exemplo, `bitcoin-cli getnetworkinfo` fornece uma variedade de informações sobre sua configuração e seu acesso a outras redes: +Por exemplo, `bitcoin-cli getnetworkinfo` fornece uma variedade de informações sobre nossa configuração e nosso acesso a outras redes: ``` $ bitcoin-cli getnetworkinfo { @@ -304,12 +305,12 @@ $ bitcoin-cli getnetworkinfo } ``` -Sinta-se à vontade para consultar qualquer um deles e usar `bitcoin-cli help` se quiser mais informações sobre o que qualquer um deles faz. +Vamos testar à vontade qualquer um deles e usar `bitcoin-cli help` se quisermos saber mais informações sobre o que qualquer um deles faz. -## Resumo: Conhecendo a configuração do seu node Bitcoin +## Resumo do Conhecendo a configuração do seu node Bitcoin -O diretório `~ /.bitcoin` contém todos os seus arquivos, enquanto `bitcoin-cli help` te retorna uma variedade de comandos, info podem ser usados para obter mais informações sobre como sua configuração e o Bitcoin funcionam. +O diretório `~/.bitcoin` contém todos os arquivos, enquanto o `bitcoin-cli help` nos retorna uma variedade de informações de comandos que podem ser usados para obter mais informações sobre como nossa configuração e o Bitcoin funcionam. -## Mas o que vem a seguir? +## O Que Vem Depois? -Continue "Compreendendo sua configuração do seu node Bitcoin" com [3.3: Setting Up Your Wallet](03_3_Setting_Up_Your_Wallet.md). \ No newline at end of file +Vamos continuar "Compreendendo a configuração do node Bitcoin" na sessão [3.3: Configurando nossa carteira](03_3_Setting_Up_Your_Wallet.md). \ No newline at end of file From 835aa32238a04199c8e9366f57a08e8ec4b8aee3 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 12:53:51 -0300 Subject: [PATCH 33/50] Session 3.3 reviewed --- ..._Interlude_Using_Command-Line_Variables.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/03_3__Interlude_Using_Command-Line_Variables.md b/pt/03_3__Interlude_Using_Command-Line_Variables.md index 0c74363..5c1f67b 100644 --- a/pt/03_3__Interlude_Using_Command-Line_Variables.md +++ b/pt/03_3__Interlude_Using_Command-Line_Variables.md @@ -1,13 +1,13 @@ # Usando variáveis de linha de comando -A seção anterior demonstrou vários comandos de linha de comando usados sem ofuscação ou interferência. No entanto, geralmente essa não é a melhor maneira de executar Bitcoin na linha de comando. Como você está lidando com variáveis longas, complexas e ilegíveis, é fácil cometer um erro se você estiver copiando essas variáveis (ou, satoshi forfend, se você as estiver digitando manualmente). Como essas variáveis podem significar a diferença entre receber e perder dinheiro real, você não _quer_ cometer erros. Por esses motivos, sugerimos enfaticamente o uso de variáveis de linha de comando para salvar endereços, assinaturas ou outras cadeias de informações longas sempre que for razoável. +A sessão anterior demonstrou vários comandos de linha de comando usados sem ofuscação ou interferência. No entanto, geralmente essa não é a melhor maneira de executar o Bitcoin usando a linha de comando. Como estamos lidando com variáveis longas, complexas e difíceis de serem lidas, é fácil cometer um erro se estivermos copiando essas variáveis (ou, perder alguns satoshis, se as digitarmos manualmente). Como essas variáveis podem significar a diferença entre receber e perder dinheiro quando usarmos a Mainnet, não _queremos_ cometer erros. Por esses motivos, sugerimos enfaticamente o uso de variáveis de linha de comando para salvar endereços, assinaturas ou outras cadeias de informações longas sempre que isso for razoável. -Se estiver usando `bash`, você pode salvar as informações em uma variável como esta: +Se estiver usando `bash`, podemos salvar as informações em uma variável como esta: ``` $ VARIABLE=$(command) ``` -Esta é uma substituição de comando simples, o equivalente a `VARIABLE = command`. O comando entre parênteses é executado e, em seguida, atribuído à VARIÁVEL. +Esta é uma substituição de um comando simples, o equivalente a `VARIABLE = command`. O comando entre parênteses é executado e, em seguida, atribuído à VARIABLE. Para criar um novo endereço, seria assim: ``` @@ -16,25 +16,25 @@ $ NEW_ADDRESS_1=$(bitcoin-cli getnewaddress "" legacy) ``` Esses comandos limpam a variável NEW_ADDRESS_1, apenas para ter certeza, e então a preenchem com os resultados do comando `bitcoin-cli getnewaddress`. -Você pode então usar o comando `echo` do seu shell para ver o seu (novo) endereço: +Podemos então usar o comando `echo` do shell para vermos nosso (novo) endereço: ``` $ echo $NEW_ADDRESS_1 mi25UrzHnvn3bpEfFCNqJhPWJn5b77a5NE ``` -Como seu endereço está em uma variável, agora você pode assinar facilmente uma mensagem para esse endereço, sem se preocupar em digitar o endereço incorretamente. É claro que você também salvará essa assinatura em uma variável! +Como nosso endereço está em uma variável, agora podemos assinar facilmente uma mensagem para esse endereço, sem nos preocupar em digitar o endereço incorretamente. É claro que também salvaremos essa assinatura em uma variável! ``` $ NEW_SIG_1=$(bitcoin-cli signmessage $NEW_ADDRESS_1 "Hello, World") $ echo $NEW_SIG_1 IPYIzgj+Rg4bxDwCyoPiFiNNcxWHYxgVcklhmN8aB2XRRJqV731Xu9XkfZ6oxj+QGCRmTe80X81EpXtmGUpXOM4= ``` -O restante deste tutorial usará esse estilo de armazenar informações em variáveis quando for prático. +O restante deste tutorial usará esse estilo de armazenamento de informações quando for mais prático. -> :book: ***Quando não é prático usar variáveis de linha de comando?*** Variáveis de linha de comando não são práticas se você precisar usar as informações em algum lugar diferente da linha de comando. Por exemplo, salvar sua assinatura pode não ser útil se você apenas tiver que enviá-la a outra pessoa por e-mail. Além disso, alguns comandos futuros produzirão objetos JSON em vez de informações simples, e as variáveis não podem ser usadas para capturar essas informações ... pelo menos não sem um _pouco_ de mais trabalho. +> :book: ***Quando não é prático usar variáveis de linha de comando?*** Variáveis de linha de comando não são práticas se precisarmos usar as informações em algum lugar diferente da linha de comando. Por exemplo, salvar a assinatura pode não ser útil se tivermos que enviá-la a outra pessoa por e-mail. Além disso, alguns comandos futuros produzirão objetos JSON ao invés de informações simples, e as variáveis não podem ser usadas para capturar essas informações, ao menos não sem um _pouco_ mais de mais trabalho. -## Resumo: Usando variáveis de linha de comando +## Resumo do Usando variáveis de linha de comando Variáveis de shell podem ser usadas para manter longas strings, minimizando as chances de erros. -## Mas o que vem a seguir? +## O Que Vem Depois? -Continue "Compreendendo a configuração do seu node Bitcoin" com [3.4: Recebendo uma transação](03_4_Receiving_a_Transaction.md). \ No newline at end of file +Vamos continuar "Compreendendo a configuração do node Bitcoin" na sessão [3.4: Recebendo uma transação](03_4_Receiving_a_Transaction.md). \ No newline at end of file From a0fcae116c176a1c14277f272169e2cc7de26c13 Mon Sep 17 00:00:00 2001 From: KoreaComK Date: Sat, 26 Jun 2021 13:54:13 -0300 Subject: [PATCH 34/50] Session 3.3 reviewed --- pt/03_3_Setting_Up_Your_Wallet.md | 91 ++++++++++++++++--------------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/pt/03_3_Setting_Up_Your_Wallet.md b/pt/03_3_Setting_Up_Your_Wallet.md index 1434ecb..724eeac 100644 --- a/pt/03_3_Setting_Up_Your_Wallet.md +++ b/pt/03_3_Setting_Up_Your_Wallet.md @@ -1,74 +1,75 @@ -# 3.3: Configurando sua carteira -Agora você está pronto para começar a trabalhar com Bitcoin. Para começar, você precisará criar um endereço para receber fundos. +# 3.3: Configurando nossa carteira -## Crie um endereço +Agora estamos prontos para começar a brincar com o Bitcoin. Para começar, precisaremos criar um endereço para receber fundos. -A primeira coisa que você precisa fazer é criar um endereço para recebimento de pagamentos. Isso é feito com o comando `bitcoin-cli getnewaddress`. Lembre-se que se você quiser mais informações sobre este comando, deve digitar `bitcoin-cli help getnewaddress`. Atualmente, existem três tipos de endereços: `legacy` e os dois tipos de endereço SegWit,` p2sh-segwit` e `bech32`. Se você não especificar de outra forma, você obterá o padrão, que atualmente é `bech32`. +## Criando um endereço -No entanto, para as próximas seções, em vez disso, usaremos endereços `legacy`, tanto porque `bitcoin-cli` teve alguns problemas iniciais com suas versões anteriores de endereços SegWit, e porque outras pessoas podem não ser capazes de enviar para endereços `bech32`. É improvável que tudo isso seja um problema para você agora, mas no momento queremos começar com exemplos de transações que (na maioria) têm garantia de funcionamento. +A primeira coisa que precisamos fazer é criar um endereço para recebimento de pagamentos. Podemos fazer isso usando o comando `bitcoin-cli getnewaddress`. Temos que lembrar que se quisermos mais informações sobre este comando, podemos digitar `bitcoin-cli help getnewaddress`. Atualmente, existem três tipos de endereços: Os `legacy` e os dois tipos de endereço SegWit, `p2sh-segwit` e `bech32`. Se não especificarmos qual queremos criar, sempre teremos por padrão o `bech32`. -Você pode exigir o endereço `legacy` como segundo argumento para `getnewaddress` ou com o argumento denominado `addresstype`. +No entanto, nas próximas sessões, usaremos endereços `legacy`, porque o `bitcoin-cli` teve alguns problemas com suas versões anteriores usando os endereços SegWit e, porque algumas pessoas podem não ser capazes de enviar seus saldos para endereços `bech32`. É improvável que tudo isso seja um problema para nós neste exato momento, mas vamos começar com exemplos de transações que (na maioria das vezes) temos a garantia que irá funcionar. + +Podemos exigir um endereço `legacy` como segundo argumento para `getnewaddress` ou com o argumento denominado `addresstype`. ``` $ bitcoin-cli getnewaddress -addresstype legacy moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B ``` -Observe que este endereço começa com um "m" (ou às vezes um "n") para significar um endereço legacy testnet. Seria um "2" para um endereço P2SH ou um "tb1" para um endereço Bech32. +Observe que este endereço começa com "m" (ou às vezes um "n") para significar um endereço legacy na rede Testnet. Seria um "2" para um endereço P2SH ou um "tb1" para um endereço Bech32. -> :link: **TESTNET vs MAINNET:** O endereço mainnet equivalente começaria com "1" (para Legacy), "3" (para P2SH) ou "bc1" (para Bech32). +> :link: **TESTNET vs MAINNET:** O endereço Mainnet equivalente começaria com "1" (para Legacy), "3" (para P2SH) ou "bc1" (para Bech32). -Anote cuidadosamente o endereço. Você precisará entregá-lo a quem enviará os fundos. +Anote cuidadosamente o endereço. Precisaremos utilizá-lo para quando recebermos bitcoins. -> :book: ***O que é um endereço Bitcoin?*** Um endereço Bitcoin é literalmente onde você recebe dinheiro. É como um endereço de e-mail, mas para fundos. Tecnicamente, é uma chave pública. No entanto, ao contrário de um endereço de e-mail, um endereço de Bitcoin deve ser considerado de uso único: use-o para receber fundos apenas _uma vez_. Quando você quiser receber fundos de outra pessoa ou em algum outro momento, gere um novo endereço. Isso é sugerido em grande parte para melhorar sua privacidade. Todo o blockchain é imutável, o que significa que os exploradores podem observar longas cadeias de transações ao longo do tempo, tornando possível determinar estatisticamente quem é você e quem são seus contatos, não importa o quão cuidadoso você seja. No entanto, se você continuar reutilizando o mesmo endereço, isso se tornará ainda mais fácil. +> :book: ***O que é um endereço Bitcoin?*** Um endereço Bitcoin é literalmente onde receberemos as moedas. É como um endereço de e-mail, mas para bitcoin. Tecnicamente, é uma chave pública. No entanto, ao contrário de um endereço de e-mail, um endereço Bitcoin deve ser considerado de uso único: Vamos usar para receber fundos apenas _uma vez_. Quando quisermos receber fundos de outra pessoa ou em algum outro momento, precisaremos gerar um novo endereço. Isso é sugerido em grande parte para melhorar nossa privacidade. Toda a blockchain é imutável, o que significa que os exploradores podem observar longas cadeias de transações ao longo do tempo, tornando possível determinar estatisticamente quem é você e quem são os nossos contatos, não importa o quão cuidadoso sejamos. No entanto, se continuarmos reutilizando o mesmo endereço, isso se tornará ainda mais fácil. -> :book: ***O que é uma carteira Bitcoin?*** Ao criar seu primeiro endereço Bitcoin, você também começou a preencher sua carteira Bitcoin. Mais precisamente, você começou a preencher o arquivo `wallet.dat` em seu diretório `~/.bitcoin/testnet3/wallets`. O arquivo `wallet.dat` contém dados sobre preferências e transações, mas mais importante, contém todos os pares de chaves que você criou: a chave pública (que é a fonte do endereço onde você recebe fundos) e a chave privada (que é como você gasta esses fundos). Na maior parte, você não terá que se preocupar com a chave privada: `bitcoind` irá usá-la quando for necessário. No entanto, isso torna o arquivo `wallet.dat` extremamente importante: se você o perder, perderá suas chaves privadas e, se perder suas chaves privadas, perderá seus fundos! +> :book: ***O que é uma carteira Bitcoin?*** Ao criar nosso primeiro endereço Bitcoin, também começamos a preencher nossa carteira Bitcoin. Mais precisamente, começamos a preencher o arquivo `wallet.dat` no nosso diretório `~/.bitcoin/testnet3/wallets`. O arquivo `wallet.dat` contém dados sobre preferências e transações, mas mais importante, contém todos os pares de chaves que criamos: A chave pública (que é a fonte do endereço onde receberemos as moedas) e a chave privada (que é como gastamos esses fundos). Na maior parte, não teremos que nos preocupar com a chave privada: O `bitcoind` irá usá-la quando for necessário. No entanto, isso torna o arquivo `wallet.dat` extremamente importante: Se o perdermos, perderemos nossas chaves privadas e, se perdermos as chaves privadas, perderemos nossos fundos! -Com um único endereço em mãos, você pode pular direto para a próxima seção e começar a receber fundos. No entanto, antes de chegarmos lá, vamos discutir brevemente os outros tipos de endereços que você encontrará no futuro e falar sobre alguns outros comandos de carteira que você pode querer usar no futuro. +Com um único endereço em mãos, podemos pular direto para a próxima seção e começar a receber alguns satoshinhos. No entanto, antes de chegarmos lá, vamos discutir brevemente os outros tipos de endereços que encontraremos no futuro e falar sobre alguns outros comandos de carteira que podemos querer usar mais pra frente. -### Conhecendo seus endereços de Bitcoin +### Conhecendo os endereços do Bitcoin -Existem três tipos de endereços Bitcoin que você pode criar com o comando RPC `getnewaddress`. Você usará um endereço `legacy` (P2PKH) aqui, enquanto se moverá para um endereço SegWit (P2SH-SegWit) ou Bech32 em [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md). +Existem três tipos de endereços Bitcoin que podemos criar com o comando RPC `getnewaddress`. Usaremos um endereço `legacy` (P2PKH) aqui, mas iremos utilizar um endereço SegWit (P2SH-SegWit) ou Bech32 na sessão [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md). -Conforme observado acima, a base de um endereço de Bitcoin é uma chave pública: alguém envia fundos para sua chave pública e você usa sua chave privada para resgatá-la. Fácil? Exceto que colocar sua chave pública lá não é totalmente seguro. No momento, se alguém tiver sua chave pública, não poderá recuperar sua chave privada (e, portanto, seus fundos); essa é a base da criptografia, que usa uma função de trapdoor para garantir que você só possa passar da chave privada para a pública, e não vice-versa. Mas o problema é que não sabemos o que o futuro pode trazer. Exceto que sabemos que os sistemas de criptografia eventualmente são quebrados pelo avanço implacável da tecnologia, então é melhor não colocar chaves públicas brutas na rede, para preparar suas transações para o futuro. +Conforme observado acima, a base de um endereço de Bitcoin é uma chave pública: Alguém envia fundos para nossa chave pública e usamos a nossa chave privada para resgatá-la. Simples, não? Exceto que colocar nossa chave pública lá não é algo seguro. No momento, se alguém tiver nossa chave pública, não poderemos recuperar nossa chave privada (e, portanto, nossos fundos). Essa é a base da criptografia, que usa uma função de _trapdoor_ para garantir que só possamos passar da chave privada para a pública, e não vice-versa. Mas o problema é que não sabemos o que o futuro pode nos trazer. Exceto que sabemos que os sistemas de criptografia eventualmente são quebrados pelo avanço implacável da tecnologia, então é melhor não colocar chaves públicas brutas na rede, para prepararmos nossas transações para o futuro. -As transações clássicas de Bitcoin criaram endereços P2PKH que adicionaram uma etapa criptográfica adicional para proteger as chaves públicas. +As transações clássicas do Bitcoin criaram endereços P2PKH que adicionaram uma etapa criptográfica adicional para proteger as chaves públicas. -> :book: ***O que é um endereço legacy (P2PKH)?*** Este é um endereço legado do tipo usado pela antiga rede Bitcoin. Iremos usá-lo em exemplos nas próximas seções. É chamado de endereço Pay to PubKey Hash (ou P2PKH) porque o endereço é um hash de 160 bits de uma chave pública. Usar um hash de sua chave pública como seu endereço cria um processo de duas etapas onde gastar os fundos você precisa revelar a chave privada e a chave pública, e aumenta a segurança futura de acordo. Esse tipo de endereço continua sendo importante para receber fundos de pessoas com software de carteira desatualizado. +> :book: ***O que é um endereço legacy (P2PKH)?*** Este é um endereço legado do tipo usado pela antiga rede Bitcoin. Iremos usá-lo em exemplos nas próximas seções. É chamado de endereço Pay to PubKey Hash (ou P2PKH) porque o endereço é um hash de 160 bits de uma chave pública. Usar um hash de sua chave pública como endereço cria um processo de duas etapas onde para gastar os fundos precisamos revelar a chave privada e a chave pública, aumentando assim a segurança futura. Esse tipo de endereço continua sendo importante para receber fundos de pessoas com softwares desatualizados. -Conforme descrito mais detalhadamente em [4.6: Criação de uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md), a Block-Size Wars do final dos anos 10 do Bitcoin resultaram em um novo tipo de endereço: SegWit. Este é o tipo de endereço preferido atualmente e deve estar totalmente integrado ao Bitcoin-Core neste exato momento. +Conforme descrito mais detalhadamente na sessão [4.6: Criando uma transação Segwit](04_6_Creating_a_Segwit_Transaction.md), a Guerra pelo Tamanho dos Blocos do final dos anos 10 do Bitcoin resultaram em um novo tipo de endereço: O SegWit. Este é o tipo de endereço preferido atualmente e deve estar totalmente integrado ao Bitcoin-Core neste exato momento. -SegWit significa simplesmente "testemunha segregada" e é uma maneira de separar as assinaturas da transação do resto da transação para reduzir o tamanho da transação. Alguns endereços SegWit entrarão em alguns de nossos exemplos anteriores a 4.6 como endereços de troco, que você verá como endereços que começam com "tb". Isso é bom porque o `bitcoin-cli` suporta inteiramente seu uso. +O SegWit significa simplesmente "Segregated Witness" e é uma maneira de separar as assinaturas da transação do resto dela para reduzir o tamanho da mesma. Alguns endereços SegWit entrarão em alguns de nossos exemplos como endereços de troco, que veremos como endereços que começam com "tb". Isso é bom porque o `bitcoin-cli` suporta inteiramente o seu uso. Existem dois endereços desse tipo: -> :book: ***O que é um endereço P2SH-SegWit (também conhecido como Nested SegWit)?*** Esta é a primeira geração do SegWit. Ele envolve o endereço SegWit em um hash de script para garantir a compatibilidade com versões anteriores. O resultado cria transações que são cerca de 25% + menores (com reduções correspondentes nas taxas de transação). +> :book: ***O que é um endereço P2SH-SegWit (também conhecido como Nested SegWit)?*** Esta é a primeira geração do SegWit. Ele envolve o endereço SegWit em um hash de script para garantir a compatibilidade com versões anteriores. O resultado cria transações que são cerca de 25% menores (com reduções correspondentes nas taxas de transação). -> :book: ***O que é um endereço Bech32 (também conhecido como SegWit nativo, também conhecido como P2WPKH)?*** Esta é a segunda geração do SegWit. Está totalmente descrito em [BIP 173] (https://en.bitcoin.it/wiki/BIP_0173). Ele cria transações que são ainda menores, mas mais notavelmente também tem algumas vantagens na criação de endereços que são menos propensos a erro humano e têm alguma correção de erro implícita além disso. Ele * não * é compatível com versões anteriores como o P2SH-SegWit era e, portanto, algumas pessoas podem não ser capazes de enviar para ele. +> :book: ***O que é um endereço Bech32 (também conhecido como SegWit nativo ou como P2WPKH)?*** Esta é a segunda geração do SegWit. Está totalmente descrito em [BIP 173](https://en.bitcoin.it/wiki/BIP_0173). Ele cria transações que são ainda menores, mas mais notavelmente também tem algumas vantagens na criação de endereços que são menos propensos a erro humano e têm algumas correções de erro implícita. Ele _não_ é compatível com versões anteriores como o P2SH-SegWit era e, portanto, algumas pessoas podem não ser capazes de enviar bitcoins para ele. -Existem outros tipos de endereços de Bitcoin, como P2PK (que paga a uma chave pública simples e está obsoleto devido à sua insegurança futura) e P2SH (que paga a um Hash de script e que é usado pelo SegWit e esta aninhado com a primeira geração endereços; vamos conhecê-lo mais detalhadamente em alguns capítulos). +Existem outros tipos de endereços de Bitcoin, como P2PK (que paga a uma chave pública simples e está obsoleto devido à sua insegurança futura) e P2SH (que paga a um Hash de script e que é usado pelo SegWit e esta aninhado com a primeira geração endereços. Vamos conhecê-lo mais detalhadamente nos próximos capítulos). -## Opcional: assine uma mensagem +## Opcional: Assinando uma mensagem -Às vezes, você precisará provar que controla um endereço Bitcoin (ou melhor, que controla sua chave privada). Isso é importante porque permite que as pessoas saibam que estão enviando fundos para a pessoa certa. Isso pode ser feito criando uma assinatura com o comando `bitcoin-cli signmessage`, na forma `bitcoin-cli signmessage [endereço] [mensagem]`. Por exemplo: +Às vezes, precisamos provar que controlamos um endereço Bitcoin (ou melhor, que controlamos a chave privada). Isso é importante porque permite que as pessoas saibam que estão enviando fundos para a pessoa certa. Isso pode ser feito criando uma assinatura com o comando `bitcoin-cli signmessage`, na forma `bitcoin-cli signmessage [endereço] [mensagem]`. Por exemplo: ``` $ bitcoin-cli signmessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "Hello, World" HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI= ``` -Você receberá a assinatura como um retorno. +O resultado é uma assinatura como um retorno. -> :book: ***What is a signature?*** A digital signature is a combination of a message and a private key that can then be unlocked with a public key. Since there's a one-to-one correspendence between the elements of a keypair, unlocking with a public key proves that the signer controlled the corresponding private key. +> :book: ***O que é uma assinatura?*** Uma assinatura digital é uma combinação de uma mensagem e uma chave privada que pode ser desbloqueada com uma chave pública. Como há uma correspondência um-para-um entre os elementos de um par de chaves, o desbloqueio com uma chave pública prova que o assinante controlou a chave privada correspondente. -Another person can then use the `bitcoin-cli verifymessage` command to verify the signature. He inputs the address in question, the signature, and the message: +Outra pessoa pode usar o comando `bitcoin-cli verifymessage` para verificar a assinatura. Ela insere o endereço em questão, a assinatura e a mensagem: ``` $ bitcoin-cli verifymessage "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" true ``` Se todos eles corresponderem, a outra pessoa saberá que pode transferir fundos com segurança para a pessoa que assinou a mensagem enviando para o endereço. -Se algum golpista estivesse criando assinaturas, isso produziria um invalido. +Se algum golpista estivesse criando assinaturas, isso produziria um erro. ``` $ bitcoin-cli verifymessage "FAKEV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" "HyIP0nzdcH12aNbQ2s2rUxLwzG832HxiO1vt8S/jw+W4Ia29lw6hyyaqYOsliYdxne70C6SZ5Utma6QY/trHZBI=" "Hello, World" error code: -3 @@ -76,19 +77,19 @@ error message: Invalid address ``` -## Opcional: descarregar sua carteira +## Opcional: Fazendo o dump da nossa carteira -Pode parecer perigoso ter todas as suas chaves privadas insubstituíveis em um único arquivo. É para isso que serve `bitcoin-cli dumpwallet`. Ele permite que você faça uma cópia de seu wallet.dat: +Pode parecer perigoso ter todas as chaves privadas insubstituíveis em um único arquivo. É para isso que serve o comando `bitcoin-cli dumpwallet`. Ele permite que façamos uma cópia do nosso arquivo `wallet.dat`: ``` $ bitcoin-cli dumpwallet ~/mywallet.txt ``` -O arquivo `mywallet.txt` em seu diretório home terá uma longa lista de chaves privadas, endereços e outras informações. Lembre-se, você não gostaria de colocar esses dados em um arquivo de texto simples, em uma configuração com fundos reais! +O arquivo `mywallet.txt` em nosso diretório home terá uma longa lista de chaves privadas, endereços e outras informações. Lembre-se, ninguém gostaria de colocar esses dados em um arquivo de texto simples, em uma configuração com saldos reais! -Você pode então recuperá-lo com `bitcoin-cli importwallet`. +Podemos então recuperá-los com o `bitcoin-cli importwallet`. ``` $ bitcoin-cli importwallet ~/mywallet.txt ``` -Mas observe que isso requer um node não prunado. +É importante observar que isso requer um node não prunado. ``` $ bitcoin-cli importwallet ~/mywallet.txt error code: -4 @@ -96,36 +97,36 @@ error message: Importing wallets is disabled when blocks are pruned ``` -## Opcional: Visualize suas chaves privadas +## Opcional: Visualizando as chaves privadas -Às vezes, você pode querer realmente olhar para as chaves privadas associadas aos seus endereços Bitcoin. Talvez você queira assinar uma mensagem ou gastar bitcoins em uma máquina diferente. Talvez você só queira fazer backup de algumas chaves privadas importantes. Você também pode fazer isso com seu arquivo de descarregado, já que ele pode ser lido por humanos. +Às vezes, podemos querer realmente olhar para as chaves privadas associadas aos nossos endereços Bitcoin. Talvez queremos assinar uma mensagem ou gastar bitcoins em uma máquina diferente. Talvez só estamos querendo fazer backup de algumas chaves privadas importantes. Também pode fazer isso com nosso arquivo criado acima, já que ele pode ser lido por humanos. ``` $ bitcoin-cli dumpwallet ~/mywallet.txt { "filename": "/home/standup/mywallet.txt" } ``` -Mais provavelmente, você deseja apenas examinar a chave privada associada a um endereço específico. Isso pode ser feito com o comando `bitcoin-cli dumpprivkey`. +Mais provavelmente, desejamos apenas examinar a chave privada associada a um endereço específico. Isso pode ser feito com o comando `bitcoin-cli dumpprivkey`. ``` $ bitcoin-cli dumpprivkey "moKVV6XEhfrBCE3QCYq6ppT7AaMF8KsZ1B" cTv75T4B3NsG92tdSxSfzhuaGrzrmc1rJjLKscoQZXqNRs5tpYhH ``` -Você pode salvar essa chave em um local seguro, de preferência em algum lugar sem conexão com a Internet. +Podemos salvar essa chave em um local seguro, de preferência em algum lugar sem conexão com a Internet. -Você também pode importar qualquer chave privada, de um despejo de carteira ou um despejo de chave individual, da seguinte maneira: +Também podemos importar qualquer chave privada, de um dump de carteira ou um dump da chave individual, da seguinte maneira: ``` $ bitcoin-cli importprivkey cW4s4MdW7BkUmqiKgYzSJdmvnzq8QDrf6gszPMC7eLmfcdoRHtHh ``` -Novamente, espere que isso exija um node não prunado. Espere que isso demore um pouco, já que o `bitcoind` precisa reler todas as transações anteriores, para ver se há alguma nova. +Novamente, é esperado que isso exija um node não prunado. Isso provavelmente vai demorar um pouco, já que o `bitcoind` precisa reler todas as transações anteriores, para ver se há alguma nova. -> :information_source: **NOTA:** Muitas carteiras modernas preferem [códigos mnemônicos](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) para gerar as sementes necessárias para criar as chaves privadas. Esta metodologia não é usada `bitcoin-cli`, então você não será capaz de gerar listas de palavras úteis para lembrar suas chaves privadas. +> :information_source: **NOTA:** Muitas carteiras modernas preferem [códigos mnemônicos](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) para gerar as seeds necessárias para criar as chaves privadas. Esta metodologia não é usada pelo `bitcoin-cli`, então não seremos capazes de gerar listas de palavras para lembrar das nossas chaves privadas. -_Você digitou aquele endereço Bitcoin que gerou, enquanto assinava uma mensagens e agora esta descarregando as chaves. Se você acha que é muito complicado, concordamos. Também está sujeito a erros, um tópico que abordaremos na próxima seção._ +_Nós digitamos aquele endereço Bitcoin que gerou, enquanto assinávamos uma mensagem e agora estamos fazendo o dump as chaves. Se por acaso achar que isso é muito complicado, os autores e tradutores também concordam com isso. Também estamos sujeitos a erros, um tópico que abordaremos na próxima sessão._ -## Resumo: Configurando sua carteira +## Resumo do Configurando nossa carteira -Você precisa criar um endereço para receber fundos. Seu endereço é armazenado em uma carteira, da qual você pode fazer backup. Você também pode fazer muito mais com um endereço, como descartar sua chave privada ou usá-la para assinar mensagens. Mas, realmente, criar esse endereço é _tudo_ que você precisa fazer para receber os fundos. +Precisamos criar um endereço para receber fundos. Nosso endereço é armazenado em uma carteira, da qual podemos fazer o backup. Podemos fazer muito coisas com nosso endereço, como fazer o dump da nossa chave privada ou usá-la para assinar mensagens. Mas, realmente, criar esse endereço é _tudo_ que precisaremos fazer para receber alguns satoshinhos. -## Mas oque vem a seguir? +## O Que Vem Depois? -Um passo para trás em "Compreendendo a configuração do seu node Bitcoin" com [Usando variáveis de linha de comandos](03_3__Interlude_Using_Command-Line_Variables.md). \ No newline at end of file +Vamos dar uma pausa no capítulo "Compreendendo a configuração do node Bitcoin" na sessão [Usando variáveis de linha de comando](03_3__Interlude_Using_Command-Line_Variables.md). \ No newline at end of file From 797229d52283095c49007f05c12e4753debbf59a Mon Sep 17 00:00:00 2001 From: namcios Date: Tue, 29 Jun 2021 12:27:15 -0300 Subject: [PATCH 35/50] Add translated README --- pt/README.md | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 222 insertions(+), 1 deletion(-) diff --git a/pt/README.md b/pt/README.md index ec090a7..ffb21c3 100644 --- a/pt/README.md +++ b/pt/README.md @@ -1 +1,222 @@ -_directory for the Portuguese translation._ +# Aprendendo Bitcoin pela Linha de Comando 2.0.1 +### _por Christopher Allen e Shannon Appelcline_ + +![](https://www.blockchaincommons.com/images/projects/lbtc-screen.png) + +Aprendendo Bitcoin pela Linha de Comando é a versão em português de [Learning Bitcoin from the Command Line](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line), um tutorial para trabalhar com Bitcoin (e Lightning) que ensina interação direta com os servidores como a maneira mais robusta e segura de começar a trabalhar com criptomoedas. + +> NOTA: Este é um rascunho em progresso, para que eu possa receber algum feedback de revisores iniciais. Ainda não está pronto para uso. + +_Este tutorial assume que você tenha um mínimo background em como utilizar a linha de comando. Caso contrário, vários tutoriais estão disponíveis, e eu tenho um para usuários de Mac em https://github.com/ChristopherA/intro-mac-command-line._ + +## Traduções + +* [Espanhol](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/spanish-translation/es) - em progresso + +Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuindo](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master#contributing) abaixo. + +## Índice + +### PARTE UM: PREPARANDO PARA O BITCOIN + +**Estado**: Finalizado. Atualizado para 0.20. + +* [1.0: Introdução à Programação com Bitcoin Core e Lightning](01_0_Introduction.md) + * [Prefácio: Introduzindo o Bitcoin](01_1_Introducing_Bitcoin.md) +* [2.0: Configurando um Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) + * [2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) + * [2.2: Configurando uma Máquina Bitcoin-Core de Outras Formas](02_2_Setting_Up_Bitcoin_Core_Other.md) + +### PARTE DOIS: USANDO BITCOIN-CLI + +**Estado:** Finalizado. Atualizado para 0.20. + +* [3.0: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md) + * [3.1: Verificando Sua Configuração do Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) + * [3.2: Conhecendo Sua Configuração do Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) + * [3.3: Configurando Sua Carteira](03_3_Setting_Up_Your_Wallet.md) + * [Prefácio: Usando Variáveis de Linha de Comando](03_3__Interlude_Using_Command-Line_Variables.md) + * [3.4: Recebendo uma Transação](03_4_Receiving_a_Transaction.md) + * [3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md) +* [4.0: Enviando Transações no Bitcoin](04_0_Sending_Bitcoin_Transactions.md) + * [4.1: Enviando Moedas da Maneira Fácil](04_1_Sending_Coins_The_Easy_Way.md) + * [4.2: Criando uma Transação Bruta](04_2_Creating_a_Raw_Transaction.md) + * [Prefácio: Usando JQ](04_2__Interlude_Using_JQ.md) + * [4.3: Criando uma Transação Bruta com Argumentos Nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) + * [4.4: Enviando Moedas com Transações Brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) + * [Prefácio: Usando Curl](04_4__Interlude_Using_Curl.md) + * [4.5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) + * [4.6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md) +* [5.0: Controlando Transações no Bitcoin](05_0_Controlling_Bitcoin_Transactions.md) + * [5.1 Atentando-se para Transações Presas](05_1_Watching_for_Stuck_Transactions.md) + * [5.2: Re-enviando uma Transação com RBF](05_2_Resending_a_Transaction_with_RBF.md) + * [5.3: Financiando uma Transação com CPFP](05_3_Funding_a_Transaction_with_CPFP.md) +* [6.0: Expandindo Transações no Bitcoin com Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) + * [6.1: Enviando uma Transação com Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [6.2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [6.3: Enviando & Gastando um Multisig Automatizado](06_3_Sending_an_Automated_Multisig.md) +* [7.0: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md) + * [7.1: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) + * [7.2: Usando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) + * [7.3: Integrando com Carteiras de Hardware](07_3_Integrating_with_Hardware_Wallets.md) +* [8.0: Expandindo Transações no Bitcoin de Outras Maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md) + * [8.1: Enviando uma Transação com um Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) + * [8.2: Enviando uma Transação com Dados](08_2_Sending_a_Transaction_with_Data.md) + +### PARTE TRÊS: PROGRAMANDO NO BITCOIN + +**Estado:** Finalizado. Atualizado para 0.20 e btcdeb. + +* [9.0: Introduzindo Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md) + * [9.1: Compreendendo a Fundação de Transações](09_1_Understanding_the_Foundation_of_Transactions.md) + * [9.2: Rodando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md) + * [9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md) + * [9.4: Programando um P2PKH](09_4_Scripting_a_P2PKH.md) + * [9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md) +* [10.0: Embutindo Scripts em Transações P2SH no Bitcoin](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md) + * [10.1: Compreendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) + * [10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md) + * [10.3: Rodando um Script no Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) + * [10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md) + * [10.5: Programando um Script Segwit](10_5_Scripting_a_Segwit_Script.md) + * [10.6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md) +* [11.0: Capacitando Timelock com Scripts no Bitcoin](11_0_Empowering_Timelock_with_Bitcoin_Scripts.md) + * [11.1: Compreendendo Opções de Timelock](11_1_Understanding_Timelock_Options.md) + * [11.2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts.md) + * [11.3: Usando CSV em Scripts](11_3_Using_CSV_in_Scripts.md) +* [12.0: Expandindo Scripts no Bitcoin](12_0_Expanding_Bitcoin_Scripts.md) + * [12.1: Usando Condicionais de Script](12_1_Using_Script_Conditionals.md) + * [12.2: Usando Outros Comandos de Script](12_2_Using_Other_Script_Commands.md) +* [13.0: Projetando Scripts Reais no Bitcoin](13_0_Designing_Real_Bitcoin_Scripts.md) + * [13.1: Escrevendo Scripts de Quebra-Cabeças](13_1_Writing_Puzzle_Scripts.md) + * [13.2: Escrevendo Scripts Complexos de Multisig](13_2_Writing_Complex_Multisig_Scripts.md) + * [13.3: Capacitando o Bitcoin com Scripts](13_3_Empowering_Bitcoin_with_Scripts.md) + +### PARTE QUATRO: USANDO TOR + +**Estado:** Finalizado. + +* [14.0: Usando Tor](14_0_Using_Tor.md) + * [14.1: Verificando Sua Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) + * [14.2: Mudando Seus Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) + * [14.3: Adicionando SSH aos Seus Serviços Ocultos](14_3_Adding_SSH_Hidden_Services.md) + +### PARTE CINCO: PROGRAMANDO COM RPC + +**Estado:** Finalizado. + +* [15.0: Conversando com o Bitcoind com C](15_0_Talking_to_Bitcoind.md) + * [15.1: Acessando o Bitcoind em C com Livrarias RPC](15_1_Accessing_Bitcoind_with_C.md) + * [15.2: Programando o Bitcoind em C com Livrarias RPC](15_2_Programming_Bitcoind_with_C.md) + * [15.3: Recebendo Notificações em C com Livrarias ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) +* [16.0: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md) + * [16.1: Configurando a Libwally](16_1_Setting_Up_Libwally.md) + * [16.2: Usando BIP39 na Libwally](16_2_Using_BIP39_in_Libwally.md) + * [16.3: Usando BIP32 na Libwally](16_3_Using_BIP32_in_Libwally.md) + * [16.4: Usando PSBTs na Libwally](16_4_Using_PSBTs_in_Libwally.md) + * [16.5: Usando Scripts na Libwally](16_5_Using_Scripts_in_Libwally.md) + * [16.6: Usando Outras Funções na Libwally](16_6_Using_Other_Functions_in_Libwally.md) + * [16.7: Integrando Libwally e Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md) +* [17.0: Conversando com o Bitcoind com Outras Linguagens](17_0_Talking_to_Bitcoind_Other.md) + * [17.1: Acessando o Bitcoind com Go](17_1_Accessing_Bitcoind_with_Go.md) + * [17.2: Acessando o Bitcoind com Java](17_2_Accessing_Bitcoind_with_Java.md) + * [17.3: Acessando o Bitcoind com Node JS](17_3_Accessing_Bitcoind_with_NodeJS.md) + * [17.4: Acessando o Bitcoind com Python](17_4_Accessing_Bitcoind_with_Python.md) + * [17.5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md) + * [17.6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md) + +### PARTE SEIS: USANDO LIGHTNING-CLI + +**Estado:** Finalizado. + +* [18.0: Compreendendo Sua Configuração Lightning](18_0_Understanding_Your_Lightning_Setup.md) + * [18.1: Verificando Sua Configuração c-lightning](18_1_Verifying_Your_Lightning_Setup.md) + * [18.2: Conhecendo Sua Configuração c-lightning](18_2_Knowing_Your_lightning_Setup.md) + * [Prefácio: Acessando um Segundo Node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md) + * [18.3: Criando um Canal Lightning](18_3_Setting_Up_a_Channel.md) +* [19.0: Usando Lightning](19_0_Using_Lightning.md) + * [19.1: Gerando um Pedido de Pagamento](19_1_Generate_a_Payment_Request.md) + * [19.2: Pagando uma Fatura](19_2_Paying_a_Invoice.md) + * [19.3: Fechando um Canal Lighnting]((19_3_Closing_a_Channel.md)) + * [19.4: Expandindo a Rede Lightning](19_4_Lightning_Network_Review.md) + +### APÊNDICES + +**Estado:** Finalizado. + +* [Apêndices](A0_Appendices.md) + * [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md) + * [Apêndice II: Compilando Bitcoin da Fonte](A2_0_Compiling_Bitcoin_from_Source.md) + * [Apêndice III: Usando o Regtest do Bitcoin](A3_0_Using_Bitcoin_Regtest.md) + +## Estado - Beta + +v2.0.1 do **Aprendendo Bitcoin pela Linha de Comando** é uma beta. Pode ainda estar sendo sujeito a revisões ou edições de terceiros, mas já pode ser utilizado para o aprendizado. + +Nós também estamos considerando o que poderíamos incluir em uma [v3.0](TODO-30.md) do curso. Se você gostaria de apoiar um trabalho desse tipo, torne-se um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons) ou nos apoie pelo nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/), e nos informe que **Aprendendo Bitcoin** foi o motivo. + +## Origem, Autores, Copyright & Licenças + +A não ser que indicado o contrário (ou neste [/README.md](./README.md) ou nos comentários nos cabeçalhos dos aquivos), os conteúdos deste repositório são Copyright © 2020 por Blockchain Commons, LLC, e licenciados sob [CC-BY](./LICENSE-CC-BY-4.0.md). + +## Apoio Financeiro + +*Aprendendo Bitcoin pela Linha de Comando* é um projeto da [Blockchain Commons](https://www.blockchaincommons.com/). Nós somos, com orgulho, uma organização de benefício social sem fins lucrativos comprometida ao desenvolvimento aberto e open source. O nosso trabalho é financiado inteiramente por doações e parcerias colaborativas com pessoas como você. Toda contribuição será gasta na construção de ferramenta abertas, tecnologias e técnicas que sustentam e avançam segurança do blockchain e da internet e promovem uma rede aberta. + +Para apoiar financeiramente o desenvolvimento futuro de `$projectname` e outros projetos, por favor considere se tornar um Patrocinador da Blockchain Commons por meio de patrocínios mensais contínuos como um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons). Você também pode apoiar a Blockchain Commons com bitcoins através do nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/). + +## Contribuindo + +Nós encorajamos contribuições públicas por meio de issues e pull requests! Por favor revise [CONTRIBUTING.md](./CONTRIBUTING.md) para detalhes sobre o nosso processo de desenvolvimento. Todas as contribuições para este repositório requerem um [Contrato de Licença do Contribuidor](./CLA.md) assinado por GPG. + +Se você gostaria de providenciar uma tradução de Aprendendo Bitcoin para outra língua, por favor veja também [TRANSLATING.md](./TRANSLATING.md). + +### Discussões + +O melhor lugar para conversar sobre a Blockchain Commons e seus projetos é na nossa área de Discussões no GitHub. + +[**Discussões Sobre Blockchain Commons**](https://github.com/BlockchainCommons/Community/discussions). Para desenvolvedores, estagiários a patrocinadores da Blockchain Commons, por favor utilize a área de discussões do [repositório da Comunidade](https://github.com/BlockchainCommons/Community) para falar sobre questões gerais da Blockchain Commons, o programa de estágio ou outros tópicos que não sejam o [Gordian System](https://github.com/BlockchainCommons/Gordian/discussions) ou os [padrões de carteira](https://github.com/BlockchainCommons/AirgappedSigning/discussions), pois cada um destes tem sua área de discussão própria. + +### Outras Questões & Problemas + +Como uma comunidade open-source e de desenvolvimento aberto, a Blockchain Commons não tem os recursos para fornecer apoio direto dos nossos projetos. Por favor considere a área de discussões como um local onde você pode receber respostas a perguntas. Alternativamente, por favor use o campo de [issues](./issues) deste repositório. Infelizmente, não podemos fazer promessas em relação ao tempo de resposta. + +Se a sua empresa requer apoio para usar os nossos projetos, por favor nos contacte diretamente para opcões. Nós podemos ser capazes de te oferecer um contrato para apoio por um de nossos contribuidores, ou poderemos te indicar outra entidade que possa oferecer o apoio contratual que você precisa. + +### Créditos + +As pessoas a seguir contribuíram diretamente para este repositório. Você pode adicionar o seu nome aqui ao se envolver. O primeiro passo é aprender como contribuir por meio da nossa documentação em [CONTRIBUTING.md](./CONTRIBUTING.md). + + +| Nome | Função | Github | Email | GPG Fingerprint | +| ----------------- | ------------------- | ------------------------------------------------- | ------------------------------------- | -------------------------------------------------- | +| Christopher Allen | Autor Líder | [@ChristopherA](https://github.com/ChristopherA) | \ | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | +| Shannon Appelcline | Autor Líder | [@shannona](https://github.com/shannona) | \ | 7EC6 B928 606F 27AD | + + +Contribuições adicionais estão listadas abaixo: + +| Função | Nomes | +| ------------------- | ---------------------------------------- | +| ***Contribuidores:*** | [gg2001](https://github.com/gg2001) (seções Go, Node.js), [gorazdko](https://github.com/gorazdko) (seção Rust), [Javier Vargas](https://github.com/javiervargas) (seções C, Java, Lightning, Tor), [jodobear](https://github.com/jodobear) (Apêndice: Compilando Bitcoin, seção Python) | +| ***Revisores:*** | Glen Willem [@gwillem](https://github.com/gwillem) | +| ***Patrocinadores:*** | Blockstream Corporation | + + +## Revelação Responsável + +Nós queremos manter todo o nosso software seguro para todos. Se você descobriu uma vulnerabilidade de segurança, nós agradeceríamos a sua ajuda em nos revelá-la de forma responsável. Infelizmente, nós não conseguimos oferecer programas de recompensa (bug bounty) no momento. + +Nós pedimos que você seja honesto e que, ao melhor de sua capacidade, não vaze informações ou prejudique qualquer usuário, seus dados, ou a comunidade de desenvolvedores. Por favor nos dê uma quantidade de tempo razoável para consertar o problema antes de publicá-lo. Não defraude nossos usuários ou nós mesmos no processo de descoberta. Nós prometemos não entrar com um processo contra pesquisadores que apontem um problema, dado que dêem o seu melhor para seguir estas diretrizes. + +### Reportando uma Vulnerabilidade + +Por favor reporte suspeitas de vulnerabilidades de segurança em um email privado para ChristopherA@BlockchainCommons.com (não utilize esse email para suporte). Por favor NÃO crie issues públicos para suspeitas de vulnerabilidades de segurança. + +As seguintes chaves podem ser utilizadas para comunicar informação confidencial para desenvolvedores: + +| Nome | Fingerprint | +| ----------------- | -------------------------------------------------- | +| Christopher Allen | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | + +Você pode importar uma chave rodando o seguinte comando com a fingerprint daquele indivíduo: `gpg --recv-keys ""` Se certifique de colocar o fingerprint entre aspas caso o mesmo contenha espaços. \ No newline at end of file From 7a791e5e62e8e9daba297cd0b95859b165654ee6 Mon Sep 17 00:00:00 2001 From: Luke Pavksy <85752004+lukedevj@users.noreply.github.com> Date: Tue, 29 Jun 2021 15:27:10 -0300 Subject: [PATCH 36/50] README.md reviewed --- pt/README.md | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 224 insertions(+), 1 deletion(-) diff --git a/pt/README.md b/pt/README.md index ec090a7..2d23cdb 100644 --- a/pt/README.md +++ b/pt/README.md @@ -1 +1,224 @@ -_directory for the Portuguese translation._ +# Aprendendo Bitcoin pela Linha de Comando 2.0.1 +### _por Christopher Allen e Shannon Appelcline_ + +![](https://www.blockchaincommons.com/images/projects/lbtc-screen.png) + +"Aprendendo Bitcoin pela Linha de Comando", esta é a versão em português de [Learning Bitcoin from the Command Line](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line), um tutorial para trabalhar com Bitcoin (e Lightning) que ensina a interação direta com os servidores da maneira mais robusta e segura, para começar a trabalhar com criptomoedas. + +> NOTA: Este é um rascunho em progresso, para que eu possa receber algum feedback de revisores iniciais. Ainda não está pronto para uso. + +_Este tutorial assume que você tenha um mínimo de background em como utilizar a linha de comando. Caso contrário, a vários tutoriais que estão disponíveis na internet, e eu possui um curso para usuários de Mac em: https://github.com/ChristopherA/intro-mac-command-line._ + +## Traduções + +* [Espanhol](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/spanish-translation/es) - em progresso + +* [Portugues](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/portuguese-translation/pt) - em progresso + +Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuindo](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/tree/master#contributing) abaixo. + +## Índice + +### PARTE UM: SE PREPARANDO PARA O BITCOIN + +**Estado**: Finalizado. Atualizado para 0.20. + +* [1.0: Introdução à Programação com Bitcoin Core e Lightning](01_0_Introduction.md) + * [Prefácio: Introduzindo o Bitcoin](01_1_Introducing_Bitcoin.md) +* [2.0: Configurando um Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) + * [2.1: Configurando um Bitcoin-Core VPS com Bitcoin Standup](02_1_Setting_Up_a_Bitcoin-Core_VPS_with_StackScript.md) + * [2.2: Configurando uma Máquina Bitcoin-Core de Outras Formas](02_2_Setting_Up_Bitcoin_Core_Other.md) + +### PARTE 2: USANDO BITCOIN-CLI + +**Estado:** Finalizado. Atualizado para 0.20. + +* [3.0: Compreendendo Sua Configuração do Bitcoin](03_0_Understanding_Your_Bitcoin_Setup.md) + * [3.1: Verificando Sua Configuração do Bitcoin](03_1_Verifying_Your_Bitcoin_Setup.md) + * [3.2: Conhecendo Sua Configuração do Bitcoin](03_2_Knowing_Your_Bitcoin_Setup.md) + * [3.3: Configurando Sua Carteira](03_3_Setting_Up_Your_Wallet.md) + * [Prefácio: Usando Variáveis de Linha de Comando](03_3__Interlude_Using_Command-Line_Variables.md) + * [3.4: Recebendo uma Transação](03_4_Receiving_a_Transaction.md) + * [3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md) +* [4.0: Enviando Transações no Bitcoin](04_0_Sending_Bitcoin_Transactions.md) + * [4.1: Enviando Moedas da Maneira Fácil](04_1_Sending_Coins_The_Easy_Way.md) + * [4.2: Criando uma Transação Bruta](04_2_Creating_a_Raw_Transaction.md) + * [Prefácio: Usando JQ](04_2__Interlude_Using_JQ.md) + * [4.3: Criando uma Transação Bruta com Argumentos Nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) + * [4.4: Enviando Moedas com Transações Brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) + * [Prefácio: Usando Curl](04_4__Interlude_Using_Curl.md) + * [4.5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) + * [4.6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md) +* [5.0: Controlando Transações no Bitcoin](05_0_Controlling_Bitcoin_Transactions.md) + * [5.1 Atentando-se para Transações Presas](05_1_Watching_for_Stuck_Transactions.md) + * [5.2: Re-enviando uma Transação com RBF](05_2_Resending_a_Transaction_with_RBF.md) + * [5.3: Financiando uma Transação com CPFP](05_3_Funding_a_Transaction_with_CPFP.md) +* [6.0: Expandindo Transações no Bitcoin com Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) + * [6.1: Enviando uma Transação com Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [6.2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [6.3: Enviando & Gastando um Multisig Automatizado](06_3_Sending_an_Automated_Multisig.md) +* [7.0: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md) + * [7.1: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) + * [7.2: Usando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_2_Using_a_Partially_Signed_Bitcoin_Transaction.md) + * [7.3: Integrando com Carteiras de Hardware](07_3_Integrating_with_Hardware_Wallets.md) +* [8.0: Expandindo Transações no Bitcoin de Outras Maneiras](08_0_Expanding_Bitcoin_Transactions_Other.md) + * [8.1: Enviando uma Transação com um Locktime](08_1_Sending_a_Transaction_with_a_Locktime.md) + * [8.2: Enviando uma Transação com Dados](08_2_Sending_a_Transaction_with_Data.md) + +### PARTE 3: PROGRAMANDO NO BITCOIN + +**Estado:** Finalizado. Atualizado para 0.20 e btcdeb. + +* [9.0: Introduzindo Scripts no Bitcoin](09_0_Introducing_Bitcoin_Scripts.md) + * [9.1: Compreendendo a Fundação de Transações](09_1_Understanding_the_Foundation_of_Transactions.md) + * [9.2: Rodando um Script no Bitcoin](09_2_Running_a_Bitcoin_Script.md) + * [9.3: Testando um Script no Bitcoin](09_3_Testing_a_Bitcoin_Script.md) + * [9.4: Programando um P2PKH](09_4_Scripting_a_P2PKH.md) + * [9.5: Programando um P2WPKH](09_5_Scripting_a_P2WPKH.md) +* [10.0: Embutindo Scripts em Transações P2SH no Bitcoin](10_0_Embedding_Bitcoin_Scripts_in_P2SH_Transactions.md) + * [10.1: Compreendendo a Fundação do P2SH](10_1_Understanding_the_Foundation_of_P2SH.md) + * [10.2: Construindo a Estrutura do P2SH](10_2_Building_the_Structure_of_P2SH.md) + * [10.3: Rodando um Script no Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md) + * [10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md) + * [10.5: Programando um Script Segwit](10_5_Scripting_a_Segwit_Script.md) + * [10.6: Gastando uma Transação P2SH](10_6_Spending_a_P2SH_Transaction.md) +* [11.0: Capacitando Timelock com Scripts no Bitcoin](11_0_Empowering_Timelock_with_Bitcoin_Scripts.md) + * [11.1: Compreendendo Opções de Timelock](11_1_Understanding_Timelock_Options.md) + * [11.2: Usando CLTV em Scripts](11_2_Using_CLTV_in_Scripts.md) + * [11.3: Usando CSV em Scripts](11_3_Using_CSV_in_Scripts.md) +* [12.0: Expandindo Scripts no Bitcoin](12_0_Expanding_Bitcoin_Scripts.md) + * [12.1: Usando Condicionais de Script](12_1_Using_Script_Conditionals.md) + * [12.2: Usando Outros Comandos de Script](12_2_Using_Other_Script_Commands.md) +* [13.0: Projetando Scripts Reais no Bitcoin](13_0_Designing_Real_Bitcoin_Scripts.md) + * [13.1: Escrevendo Scripts de Quebra-Cabeças](13_1_Writing_Puzzle_Scripts.md) + * [13.2: Escrevendo Scripts Complexos de Multisig](13_2_Writing_Complex_Multisig_Scripts.md) + * [13.3: Capacitando o Bitcoin com Scripts](13_3_Empowering_Bitcoin_with_Scripts.md) + +### PARTE 4: USANDO TOR + +**Estado:** Finalizado. + +* [14.0: Usando Tor](14_0_Using_Tor.md) + * [14.1: Verificando Sua Configuração do Tor](14_1_Verifying_Your_Tor_Setup.md) + * [14.2: Mudando Seus Serviços Ocultos do Bitcoin](14_2_Changing_Your_Bitcoin_Hidden_Services.md) + * [14.3: Adicionando SSH aos Seus Serviços Ocultos](14_3_Adding_SSH_Hidden_Services.md) + +### PARTE 5: PROGRAMANDO COM RPC + +**Estado:** Finalizado. + +* [15.0: Conversando com o Bitcoind com C](15_0_Talking_to_Bitcoind.md) + * [15.1: Acessando o Bitcoind em C com Livrarias RPC](15_1_Accessing_Bitcoind_with_C.md) + * [15.2: Programando o Bitcoind em C com Livrarias RPC](15_2_Programming_Bitcoind_with_C.md) + * [15.3: Recebendo Notificações em C com Livrarias ZMQ](15_3_Receiving_Bitcoind_Notifications_with_C.md) +* [16.0: Programando Bitcoin com Libwally](16_0_Programming_with_Libwally.md) + * [16.1: Configurando a Libwally](16_1_Setting_Up_Libwally.md) + * [16.2: Usando BIP39 na Libwally](16_2_Using_BIP39_in_Libwally.md) + * [16.3: Usando BIP32 na Libwally](16_3_Using_BIP32_in_Libwally.md) + * [16.4: Usando PSBTs na Libwally](16_4_Using_PSBTs_in_Libwally.md) + * [16.5: Usando Scripts na Libwally](16_5_Using_Scripts_in_Libwally.md) + * [16.6: Usando Outras Funções na Libwally](16_6_Using_Other_Functions_in_Libwally.md) + * [16.7: Integrando Libwally e Bitcoin-CLI](16_7_Integrating_Libwally_and_Bitcoin-CLI.md) +* [17.0: Conversando com o Bitcoind com Outras Linguagens](17_0_Talking_to_Bitcoind_Other.md) + * [17.1: Acessando o Bitcoind com Go](17_1_Accessing_Bitcoind_with_Go.md) + * [17.2: Acessando o Bitcoind com Java](17_2_Accessing_Bitcoind_with_Java.md) + * [17.3: Acessando o Bitcoind com Node JS](17_3_Accessing_Bitcoind_with_NodeJS.md) + * [17.4: Acessando o Bitcoind com Python](17_4_Accessing_Bitcoind_with_Python.md) + * [17.5: Acessando o Bitcoind com Rust](17_5_Accessing_Bitcoind_with_Rust.md) + * [17.6: Acessando o Bitcoind com Swift](17_6_Accessing_Bitcoind_with_Swift.md) + +### PARTE 6: USANDO LIGHTNING-CLI + +**Estado:** Finalizado. + +* [18.0: Compreendendo Sua Configuração Lightning](18_0_Understanding_Your_Lightning_Setup.md) + * [18.1: Verificando Sua Configuração c-lightning](18_1_Verifying_Your_Lightning_Setup.md) + * [18.2: Conhecendo Sua Configuração c-lightning](18_2_Knowing_Your_lightning_Setup.md) + * [Prefácio: Acessando um Segundo Node Lightning](18_2__Interlude_Accessing_a_Second_Lightning_Node.md) + * [18.3: Criando um Canal Lightning](18_3_Setting_Up_a_Channel.md) +* [19.0: Usando Lightning](19_0_Using_Lightning.md) + * [19.1: Gerando um Pedido de Pagamento](19_1_Generate_a_Payment_Request.md) + * [19.2: Pagando uma Fatura](19_2_Paying_a_Invoice.md) + * [19.3: Fechando um Canal Lighnting]((19_3_Closing_a_Channel.md)) + * [19.4: Expandindo a Rede Lightning](19_4_Lightning_Network_Review.md) + +### APÊNDICES + +**Estado:** Finalizado. + +* [Apêndices](A0_Appendices.md) + * [Apêndice I: Compreendendo o Bitcoin Standup](A1_0_Understanding_Bitcoin_Standup.md) + * [Apêndice II: Compilando Bitcoin da Fonte](A2_0_Compiling_Bitcoin_from_Source.md) + * [Apêndice III: Usando o Regtest do Bitcoin](A3_0_Using_Bitcoin_Regtest.md) + +## Estado - Beta + +v2.0.1 do **Aprendendo Bitcoin pela Linha de Comando** é uma beta. Pode ainda estar sendo sujeito a revisões ou edições de terceiros, mas já pode ser utilizado para o aprendizado. + +Nós também estamos considerando o que poderíamos incluir em uma [v3.0](TODO-30.md) do curso. Se você gostaria de apoiar um trabalho desse tipo, torne-se um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons) ou nos apoie pelo nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/), e nos informe que **Aprendendo Bitcoin** foi o motivo. + +## Origem, Autores, Copyright & Licenças + +A não ser que indicado o contrário (ou neste [/README.md](./README.md) ou nos comentários nos cabeçalhos dos aquivos), os conteúdos deste repositório são Copyright © 2020 por Blockchain Commons, LLC, e licenciados sob [CC-BY](./LICENSE-CC-BY-4.0.md). + +## Apoio Financeiro + +*Aprendendo Bitcoin pela Linha de Comando* é um projeto da [Blockchain Commons](https://www.blockchaincommons.com/). Nós somos, com orgulho, uma organização de benefício social sem fins lucrativos comprometida ao desenvolvimento aberto e open source. O nosso trabalho é financiado inteiramente por doações e parcerias colaborativas com pessoas como você. Toda contribuição será gasta na construção de ferramenta abertas, tecnologias e técnicas que sustentam e avançam segurança do blockchain e da internet e promovem uma rede aberta. + +Para apoiar financeiramente o desenvolvimento futuro de `$projectname` e outros projetos, por favor considere se tornar um Patrocinador da Blockchain Commons por meio de patrocínios mensais contínuos como um [Patrocinador no GitHub](https://github.com/sponsors/BlockchainCommons). Você também pode apoiar a Blockchain Commons com bitcoins através do nosso [Servidor BTCPay](https://btcpay.blockchaincommons.com/). + +## Contribuindo + +Nós encorajamos contribuições públicas por meio de issues e pull requests! Por favor revise [CONTRIBUTING.md](./CONTRIBUTING.md) para detalhes sobre o nosso processo de desenvolvimento. Todas as contribuições para este repositório requerem um [Contrato de Licença do Contribuidor](./CLA.md) assinado por GPG. + +Se você gostaria de providenciar uma tradução de Aprendendo Bitcoin para outra língua, por favor veja também [TRANSLATING.md](./TRANSLATING.md). + +### Discussões + +O melhor lugar para conversar sobre a Blockchain Commons e seus projetos é na nossa área de Discussões no GitHub. + +[**Discussões Sobre Blockchain Commons**](https://github.com/BlockchainCommons/Community/discussions). Para desenvolvedores, estagiários a patrocinadores da Blockchain Commons, por favor utilize a área de discussões do [repositório da Comunidade](https://github.com/BlockchainCommons/Community) para falar sobre questões gerais da Blockchain Commons, o programa de estágio ou outros tópicos que não sejam o [Gordian System](https://github.com/BlockchainCommons/Gordian/discussions) ou os [padrões de carteira](https://github.com/BlockchainCommons/AirgappedSigning/discussions), pois cada um destes tem sua área de discussão própria. + +### Outras Questões & Problemas + +Como uma comunidade open-source e de desenvolvimento aberto, a Blockchain Commons não tem os recursos para fornecer apoio direto dos nossos projetos. Por favor considere a área de discussões como um local onde você pode receber respostas a perguntas. Alternativamente, por favor use o campo de [issues](./issues) deste repositório. Infelizmente, não podemos fazer promessas em relação ao tempo de resposta. + +Se a sua empresa requer apoio para usar os nossos projetos, por favor nos contacte diretamente para opcões. Nós podemos ser capazes de te oferecer um contrato para apoio por um de nossos contribuidores, ou poderemos te indicar outra entidade que possa oferecer o apoio contratual que você precisa. + +### Créditos + +As pessoas a seguir contribuíram diretamente para este repositório. Você pode adicionar o seu nome aqui ao se envolver. O primeiro passo é aprender como contribuir por meio da nossa documentação em [CONTRIBUTING.md](./CONTRIBUTING.md). + + +| Nome | Função | Github | Email | GPG Fingerprint | +| ----------------- | ------------------- | ------------------------------------------------- | ------------------------------------- | -------------------------------------------------- | +| Christopher Allen | Autor Líder | [@ChristopherA](https://github.com/ChristopherA) | \ | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | +| Shannon Appelcline | Autor Líder | [@shannona](https://github.com/shannona) | \ | 7EC6 B928 606F 27AD | + + +Contribuições adicionais estão listadas abaixo: + +| Função | Nomes | +| ------------------- | ---------------------------------------- | +| ***Contribuidores:*** | [gg2001](https://github.com/gg2001) (seções Go, Node.js), [gorazdko](https://github.com/gorazdko) (seção Rust), [Javier Vargas](https://github.com/javiervargas) (seções C, Java, Lightning, Tor), [jodobear](https://github.com/jodobear) (Apêndice: Compilando Bitcoin, seção Python) | +| ***Revisores:*** | Glen Willem [@gwillem](https://github.com/gwillem) | +| ***Patrocinadores:*** | Blockstream Corporation | + + +## Revelação Responsável + +Nós queremos manter todo o nosso software seguro para todos. Se você descobriu uma vulnerabilidade de segurança, nós agradeceríamos a sua ajuda em nos revelá-la de forma responsável. Infelizmente, nós não conseguimos oferecer programas de recompensa (bug bounty) no momento. + +Nós pedimos que você seja honesto e que, ao melhor de sua capacidade, não vaze informações ou prejudique qualquer usuário, seus dados, ou a comunidade de desenvolvedores. Por favor nos dê uma quantidade de tempo razoável para consertar o problema antes de publicá-lo. Não defraude nossos usuários ou nós mesmos no processo de descoberta. Nós prometemos não entrar com um processo contra pesquisadores que apontem um problema, dado que dêem o seu melhor para seguir estas diretrizes. + +### Reportando uma Vulnerabilidade + +Por favor reporte suspeitas de vulnerabilidades de segurança em um email privado para ChristopherA@BlockchainCommons.com (não utilize esse email para suporte). Por favor NÃO crie issues públicos para suspeitas de vulnerabilidades de segurança. + +As seguintes chaves podem ser utilizadas para comunicar informação confidencial para desenvolvedores: + +| Nome | Fingerprint | +| ----------------- | -------------------------------------------------- | +| Christopher Allen | FDFE 14A5 4ECB 30FC 5D22 74EF F8D3 6C91 3574 05ED | + +Você pode importar uma chave rodando o seguinte comando com a fingerprint daquele indivíduo: `gpg --recv-keys ""` Se certifique de colocar o fingerprint entre aspas caso o mesmo contenha espaços. \ No newline at end of file From 3fe95b214a4a24b094bca9d0b8b5df3a52e29d5c Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 15:56:21 -0300 Subject: [PATCH 37/50] Review 04_0 --- pt/04_0_Sending_Bitcoin_Transactions.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/04_0_Sending_Bitcoin_Transactions.md b/pt/04_0_Sending_Bitcoin_Transactions.md index f906763..1443bd3 100644 --- a/pt/04_0_Sending_Bitcoin_Transactions.md +++ b/pt/04_0_Sending_Bitcoin_Transactions.md @@ -1,14 +1,14 @@ -# Capítulo 4: Enviando transações no Bitcoin +# Capítulo 4: Enviando Transações no Bitcoin Este capítulo descreve três métodos diferentes para enviar bitcoins para endereços P2PKH normais à partir da linha de comando, usando apenas o ```bitcoin-cli```. -## Objetivos deste capítulo +## Objetivos deste Capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: * Decidir como enviar dinheiro usando o Bitcoin; * Criar uma transação bruta; - * Usar a aritmética para calcular as taxas. + * Usar aritmética para calcular as taxas. Os objetivos secundários incluem a capacidade de: @@ -20,10 +20,10 @@ Os objetivos secundários incluem a capacidade de: ## Tabela de Conteúdo - * [Seção 1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md) - * [Seção 2: Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md) - * [Prefácio: Usando o JQ](04_2__Interlude_Using_JQ.md) - * [Seção 3: Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) - * [Seção 4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) - * [Seção 5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) - * [Seção 6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md) \ No newline at end of file + * [Seção 1: Enviando Moedas da Maneira Fácil](04_1_Sending_Coins_The_Easy_Way.md) + * [Seção 2: Criando uma Transação Bruta](04_2_Creating_a_Raw_Transaction.md) + * [Prefácio: Usando JQ](04_2__Interlude_Using_JQ.md) + * [Seção 3: Criando uma Transação Bruta com Argumentos Nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) + * [Seção 4: Enviando Moedas com Transações Brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md) + * [Seção 5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md) + * [Seção 6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md) \ No newline at end of file From 7f643a44784d4db44274169b62775a965b4bd4f9 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 16:20:11 -0300 Subject: [PATCH 38/50] Review 04_1 --- pt/04_1_Sending_Coins_The_Easy_Way.md | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pt/04_1_Sending_Coins_The_Easy_Way.md b/pt/04_1_Sending_Coins_The_Easy_Way.md index 6131040..c99e251 100644 --- a/pt/04_1_Sending_Coins_The_Easy_Way.md +++ b/pt/04_1_Sending_Coins_The_Easy_Way.md @@ -1,16 +1,16 @@ -# 4.1: Enviando bitcoins no modo easy +# 4.1: Enviando Moedas da Maneira Fácil -O ```bitcoin-cli``` oferece três principais maneiras de enviar bitcoins: Utilizando um simples comando; Utilizando uma transação bruta e; Utilizando uma transação bruta com cálculos. Cada um possui seus prós e contras. Este primeiro método de envio será o mais simples. +O ```bitcoin-cli``` oferece três principais maneiras de enviar bitcoins: Utilizando um simples comando; Utilizando uma transação bruta e; Utilizando uma transação bruta com cálculos. Cada uma possui seus prós e contras. Este primeiro método de envio será o mais simples. -## Definindo sua taxa de transação +## Definindo Sua Taxa de Transação Antes de enviar qualquer bitcoin pela rede, devemos pensar sobre as taxas de transação que iremos pagar. -> :book: ***O que é uma taxa de transação?*** Não existe almoço grátis. Os mineradores adicionam as transações nos blocos porque são pagos para fazer isso. Eles não apenas são pagos pela rede para criar o bloco, mas também são pagos pelas pessoas que realizam as transações para incluí-las na blockchain. Se não pagarmos a taxa, nossa transação pode ficar travada... Para sempre (ou, até que seja salva por alguns dos truques que falaremos no [capítulo cinco](05_0_Controlling_Bitcoin_Transactions.md)). +> :book: ***O que é uma taxa de transação?*** Não existe almoço grátis. Os mineradores adicionam as transações nos blocos porque são pagos para fazer isso. Eles não apenas são pagos pela rede para criar o bloco, mas também são pagos pelas pessoas que realizam as transações para incluí-las na blockchain. Se não pagarmos a taxa, nossa transação pode ficar travada... para sempre (ou, até que seja salva por alguns dos truques que falaremos no [capítulo cinco](05_0_Controlling_Bitcoin_Transactions.md)). -Ao usar métodos simples e automatizados para criar transações, conforme descrito aqui e na sessão [§4.5: Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o Bitcoin calculará as taxas de transação para nós. Isso é feito usando taxas flutuantes, onde o ```bitcoind``` observa quanto tempo as transações estão demorando para confirmar e calcula automaticamente o que devemos gastar. +Ao usar métodos simples e automatizados para criar transações, conforme descrito aqui e na sessão [§4.5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o Bitcoin calculará as taxas de transação para nós. Isso é feito usando taxas flutuantes, onde o ```bitcoind``` observa quanto tempo as transações estão demorando para confirmar e calcula automaticamente o que devemos gastar. -Podemos ter um controle dessas informações colocando os valores racionais no nosso arquivo ```~/.bitcoin/bitcoin.conf```. Os valores de baixo custo a seguir garantiriam que houvesse uma taxa de transação mínima de 10.000 satoshis por kByte de dados em nossa transação e solicitariam que as taxas flutuantes calculassem uma boa quantia para colocar a nossa transação nos próximos seis blocos. +Podemos ter um controle dessas informações colocando os valores racionais no nosso arquivo ```~/.bitcoin/bitcoin.conf```. Os valores de baixo custo a seguir garantiríam que houvesse uma taxa de transação mínima de 10.000 satoshis por kByte de dados em nossa transação e solicitaríam que as taxas flutuantes calculassem uma boa quantia para colocar a nossa transação nos próximos seis blocos. ``` mintxfee=0.0001 txconfirmtarget=6 @@ -20,7 +20,7 @@ No entanto, como iremos partir do pressuposto que ninguém que esteja fazendo es mintxfee=0.001 txconfirmtarget=1 ``` -Devemos inseri-los no arquivo ```~/.bitcoin/bitcoin.conf```, na seção principal, no início do arquivo ou se quisermos ter a certeza de nunca iremos utilizá-lo em outro lugar, podemos colocar na sessão ```[test]```. +Devemos inserí-los no arquivo ```~/.bitcoin/bitcoin.conf```, na seção principal, no início do arquivo ou se quisermos ter a certeza que nunca iremos utilizá-lo em outro lugar, podemos colocar na seção ```[test]```. Para trabalharmos neste tutorial, estamos dispostos a gastar 100.000 satoshis por kB em cada transação, e queremos colocar cada transação no próximo bloco! Para colocar isso em uma perspectiva para melhor entendimento, uma transação simples é executada com um tamanho de 0,25 KB a 1 KB, então estaremos pagando algo em torno de 25 mil a 100 mil satoshis, sendo que atualmente, taxas acima de 10 mil são consideradas altíssimas para transações de quantidade média. @@ -30,13 +30,13 @@ $ bitcoin-cli stop $ bitcoind -daemon ``` -## Obtendo um endereço +## Obtendo um Endereço -Precisamos encontrar algum endereço para enviar nossas moedas. Normalmente, alguém nos envia em um endereço e talvez nos dê uma assinatura para provar que é o proprietário desse endereço. Como alternativa, podemos nos fornecer um QR code para que possamos digitalizar, evitando assim possíveis erros de digitação na hora de colocar o endereço no local do destinatário. Em nosso caso, vamos enviar os bitcoins para `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, que é o endereço de retorno de um antigo fauce da rede Testenet. +Precisamos encontrar algum endereço para qual enviar nossas moedas. Normalmente, alguém nos envia um endereço e talvez nos dê uma assinatura para provar que é o proprietário desse endereço. Como alternativa, podemos fornecer um QR code para que possamos digitalizar, evitando assim possíveis erros de digitação na hora de colocar o endereço no local do destinatário. Em nosso caso, vamos enviar os bitcoins para `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, que é o endereço de retorno de um antigo faucet da rede Testenet. > :book: ***O que é um QR code?*** Um QR code é apenas um jeito diferente de passar o endereço Bitcoin. Muitas carteiras geram os QR codes para nós, enquanto alguns sites tentam convertê-los em um endereço usando o QR code. Obviamente, só podemos aceitar um QR code de um site no qual confiamos. Um pagador pode usar um leitor de código de barras para ler o código QR e, em seguida, pagá-lo. -## Enviando os bitcoins +## Enviando os Bitcoins Agora estamos prontos para enviar alguns bitcoins. Na verdade, isso é bastante simples por meio da linha de comando. Basta usar ```bitcoin-cli sendtoaddress [endereço] [quantidade]```. Portanto, para enviar uns satoshinhos para o endereço `n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi`, basta fazer o seguinte: ``` @@ -51,13 +51,13 @@ Precisamos nos certificar de que o endereço digitado é o lugar para onde desej Iremos receber um txid de retorno quando usarmos este comando. -> ❕ Você pode acabar com um código de erro se não tivermos bitcoins suficientes na carteira para fazer a transação. Dependendo do nosso saldo atual, que podemos acessar usando o ```bitcoin-cli getbalance```, pode ser necessário ajustar o valor que iremos enviar para que bata com o valor que está sendo enviado, não se esquecendo da taxa de transação no meio deste processo. Se o nosso saldo atual for 0,001, podemos tentar enviar 0,0001. Como alternativa, seria melhor tirar a taxa que esperamos pagar que foi enviada na mensagem de erro do nosso saldo atual. Esta é uma boa prática, pois muitas carteiras esperam que calculemos nosso próprio valor + taxas ao fazermos as transações, mesmo as carteiras mais populares usam essa premissa. +> ❕ Você pode acabar com um código de erro se não tivermos bitcoins suficientes na carteira para fazer a transação. Dependendo do nosso saldo atual, que podemos acessar usando o ```bitcoin-cli getbalance```, pode ser necessário ajustar o valor que iremos enviar para que bata com o valor que está sendo enviado, não se esquecendo da taxa de transação no meio deste processo. Se o nosso saldo atual for 0,001, podemos tentar enviar 0,0001. Como alternativa, seria melhor tirar a taxa que esperamos pagar que foi enviada na mensagem de erro do nosso saldo atual. Esta é uma boa prática, pois muitas carteiras esperam que calculemos nosso próprio valor + taxas ao fazermos as transações, mesmo dentre as corretoras mais populares. > :warning: **ATENÇÃO:** O comando ```bitcoin-cli``` realmente gera comandos usando o JSON-RPC quando está se comunicando com o bitcoind. Eles podem ser muito exigentes. Este é um exemplo: Se listarmos a quantidade de bitcoin sem o zero à esquerda (ou seja usando ".1" em vez de "0.1"), o ```bitcoin-cli``` irá acusar um erro com uma mensagem misteriosa. -> :warning: **ATENÇÃO:** Mesmo se formos cuidadosos com nossos dados, é possível que haja este erro: _"Fee estimation failed. Fallbackfee is disabled"_. De maneira geral, isso significa que nosso ```bitcoind``` local não tem informações suficientes para estimar as taxas. Não é para vermos isso se estivermos esperado que nossa blockchain sincronize e configure nosso sistema com o Bitcoin Standup. Mas se não estivermos totalmente sincronizados, podemos nos deparar com este erro. Também pode ser que não estejamos usando um ```bitcoin.conf``` padrão: A informação ```blocksonly = 1``` fará com que nosso ```bitcoind``` não consiga estimar as taxas. +> :warning: **ATENÇÃO:** Mesmo se formos cuidadosos com nossos dados, é possível que haja este erro: _"Fee estimation failed. Fallbackfee is disabled"_. De maneira geral, isso significa que nosso ```bitcoind``` local não tem informações suficientes para estimar as taxas. Não é para vermos isso se tivermos esperado que nossa blockchain sincronize e configure nosso sistema com o Bitcoin Standup. Mas se não estivermos totalmente sincronizados, podemos nos deparar com este erro. Também pode ser que não estejamos usando um ```bitcoin.conf``` padrão: A informação ```blocksonly = 1``` fará com que nosso ```bitcoind``` não consiga estimar as taxas. -## Examinando nossa transação +## Examinando Nossa Transação Podemos ver nossa transação usando o ID de transação: ``` @@ -89,14 +89,14 @@ Você pode ver não apenas o valor transferido (0,001 BTC), mas também uma taxa Enquanto esperamos que ela seja confirmada, podemos notar que o ```bitcoin-cli getbalance``` mostra que nosso dinheiro já foi debitado. Da mesma forma, o ```bitcoin-cli listunspent``` mostrará que uma transação inteira foi perdida, mesmo que fosse mais do que o que queríamos enviar. Há uma razão para isso: Sempre que temos moedas entrando, precisamos enviar _tudo_ junto, e temos que fazer um pouco de malabarismos se quisermos realmente ficar com parte dele! Mais uma vez, o ```sendtoaddress``` cuida de tudo isso para nós, o que significa que não precisamos nos preocupar em fazer qualquer alteração até enviar uma transação bruta. Nesse caso, uma nova transação aparecerá com nossa alteração quando nosso envio for incorporado a um bloco. -## Resumo do Enviando bitcoins no modo easy +## Resumo: Enviando Moedas da Maneira Fácil Para enviar moedas facilmente, precisamos nos certificar de que nossos padrões de transação sejam racionais, obtendo um endereço e enviando as nossas moedas para lá. É por isso que esse modo é o mais fácil deles! -> :fire: ***Qual é o poder de enviar moedas no modo easy?*** -> _As vantagens._ É fácil. Não precisamos nos preocupar com coisas misteriosas como UTXOs. Não precisamos calcular as taxas de transação manualmente, então, é provável que não iremos cometer erros que custem grandes valores Se o nosso único objetivo é sentar na frente do computador e enviar alguns bitcoins, este é o caminho certo para fazer isso. -> _As desvantagens._ É alto nível. Temos muito pouco controle sobre o que está acontecendo e não podemos fazer nada demais. Se estamos planejando desenvolver um software mais complexo utilizando o Bitcoin ou se desejamos um entendimento mais profundo de como o Bitcoin funciona, então o modo easy é apenas um carrossel sem graça antes de chegarmos nas montanhas russas. +> :fire: ***Qual é o poder de enviar moedas da maneira fácil?*** +> _As vantagens._ É fácil. Não precisamos nos preocupar com coisas misteriosas como UTXOs. Não precisamos calcular as taxas de transação manualmente, então, é provável que não iremos cometer erros que custem grandes valores. Se o nosso único objetivo é sentar na frente do computador e enviar alguns bitcoins, este é o caminho certo para fazer isso. +> _As desvantagens._ É alto nível. Temos muito pouco controle sobre o que está acontecendo e não podemos fazer nada demais. Se estamos planejando desenvolver um software mais complexo utilizando o Bitcoin ou se desejamos um entendimento mais profundo de como o Bitcoin funciona, então a maneira fácil é apenas um carrossel sem graça antes de chegarmos nas montanhas russas. ## O Que Vem Depois? -Vamos continuar "Enviando Transações de Bitcoin" na sessão [§4.2 Criando uma transação bruta](04_2_Creating_a_Raw_Transaction.md). \ No newline at end of file +Vamos continuar "Enviando Transações no Bitcoin" na sessão [§4.2 Criando Uma Transação Bruta](04_2_Creating_a_Raw_Transaction.md). \ No newline at end of file From 36613e34510042b8363c3841b239845521fb64ae Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 16:44:42 -0300 Subject: [PATCH 39/50] Review 04_2 --- pt/04_2_Creating_a_Raw_Transaction.md | 47 +++++++++++++-------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/pt/04_2_Creating_a_Raw_Transaction.md b/pt/04_2_Creating_a_Raw_Transaction.md index 4a5f0b6..64399ff 100644 --- a/pt/04_2_Creating_a_Raw_Transaction.md +++ b/pt/04_2_Creating_a_Raw_Transaction.md @@ -1,18 +1,18 @@ -# 4.2 Criando uma transação bruta +# 4.2 Criando uma Transação Bruta -Agora estamos pronto para criar transações brutas no Bitcoin. Isso permite que enviemos dinheiro, mas criemos as transações com a precisão desejada. Nesta primeira seção, iremos nos concentrar em uma transação simples de uma entrada e uma saída. Este tipo de transação _não_ é realmente útil, porque raramente vamos querer enviar todo o nosso dinheiro para uma pessoa (a menos que estejamos apenas encaminhando, como se estivesse movendo coisas de uma carteira para outra). Portanto, esse _não é o melhor método_ para enviar dinheiro. É apenas um conteúdo fundamental para _realmente_ enviar dinheiro com uma transação bruta. +Agora estamos prontos para criar transações brutas no Bitcoin. Isso permite que enviemos dinheiro, mas que criemos as transações com a precisão desejada. Nesta primeira seção, iremos nos concentrar em uma transação simples de uma entrada e uma saída. Este tipo de transação _não_ é realmente útil, porque raramente vamos querer enviar todo o nosso dinheiro para uma pessoa (a menos que estejamos apenas encaminhando, como se estivesse movendo coisas de uma carteira para outra). Portanto, esse _não é o melhor método_ para enviar dinheiro. É apenas um conteúdo fundamental para _realmente_ enviar dinheiro com uma transação bruta. -## Compreendendo a transação no Bitcoin +## Compreendendo a Transação no Bitcoin Antes de mergulhar na criação de transações brutas, devemos nos certificar de que entendemos como uma transação no Bitcoin funciona. Tudo gira entorno dos UTXOs. -> :book: ***O que é um UTXO?*** Quando recebemos dinheiro em nossa carteira Bitcoin, ele aparece como uma transação individual. Cada uma dessas transações é chamada de saída de transação não gasta (Unspent Transaction Output em inglês, mais conhecida como UTXO). Não importa se vários pagamentos foram feitos para o mesmo endereço ou para vários endereços: Cada transação recebida permanece distinta na carteira como um UTXO. +> :book: ***O que é um UTXO?*** Quando recebemos dinheiro em nossa carteira Bitcoin, ele aparece como uma transação individual. Cada uma dessas transações é chamada de "Saída de Transação Não-Gasta" (Unspent Transaction Output em inglês, mais conhecido como UTXO). Não importa se vários pagamentos foram feitos para o mesmo endereço ou para vários endereços: cada transação recebida permanece distinta na carteira como um UTXO. Ao criarmos uma nova transação de saída, reunimos um ou mais UTXOs, cada um representando um pouquinho do dinheiro que recebemos. Nós os usamos como entradas para uma nova transação. Juntos, o valor deles deve ser igual ao que desejamos gastar _ou mais do que o total_. Em seguida, geramos uma ou mais saídas, que dão o dinheiro representado pelas entradas a uma ou mais pessoas. Isso cria novos UTXOs para os destinatários, que podem então usá-los para financiar transações futuras. Aqui está o truque: _Todos os UTXOs que coletarmos são gastos na íntegra!_ Isso significa que se quisermos enviar apenas parte do dinheiro em um UTXO para outra pessoa, também precisamos gerar uma saída adicional que envia o resto para nós! Por enquanto, não vamos nos preocupar com isso, mas o uso de um endereço de mudança será vital ao passar da teoria deste capítulo para transações mais práticas. -## Listando as transações não gastas +## Listando as Transações Não-Gastas Para criar uma nova transação bruta, devemos saber quais UTXOs estão disponíveis para gastar. Podemos determinar essas informações com o comando ```bitcoin-cli listunspent```: ``` @@ -66,14 +66,13 @@ Quando quisermos gastar um UTXO, não é suficiente apenas saber o id da transa Portanto, o txid+vout=UTXO. Essa será a base de qualquer transação bruta. -## Escrevendo uma transação bruta com uma saída +## Escrevendo uma Transação Bruta Com Uma Saída -You're now ready to write a simple, example raw transaction that shows how to send the entirety of a UTXO to another party. As noted, this is not necessarily a very realistic real-world case. -Agora estamos prontos para escrever um exemplo simples de transação bruta que mostra como enviar um UTXO inteiro para outra parte. Conforme falamos anteriormente, este não é um caso muito realista. +Agora estamos prontos para escrever um exemplo simples de transação bruta que mostra como enviar um UTXO inteiro para outra pessoa. Conforme falamos anteriormente, este não é um caso muito realista. -> :warning: **Atenção:** É muito fácil perder dinheiro com uma transação bruta. Considere que todas as instruções sobre como enviar bitcoins por meio de transações brutas são _muito_, _muito_ perigosas. Sempre que estiver enviando moedas na _mainnet_ para outras pessoas, devemos usar um dos outros métodos explicados neste capítulo. Criar transações brutas é extremamente útil se estivermos escrevendo programas para o bitcoin, mas _só_ neste caso. Por exemplo: Ao escrever este exemplo para uma versão anterior deste tutorial, acidentalmente gastamos a transação errada, embora tivessemos cerca de 10 vezes mais. Quase tudo isso foi enviado para os mineradores. +> :warning: **ATENÇÃO:** É muito fácil perder dinheiro com uma transação bruta. Considere que todas as instruções sobre como enviar bitcoins por meio de transações brutas são _muito_, _muito_ perigosas. Sempre que estiver enviando moedas na _mainnet_ para outras pessoas, devemos usar um dos outros métodos explicados neste capítulo. Criar transações brutas é extremamente útil se estivermos escrevendo programas para o bitcoin, mas _só_ neste caso. (Por exemplo: ao escrever este exemplo para uma versão anterior deste tutorial, acidentalmente gastamos a transação errada, embora tivéssemos cerca de 10 vezes mais. Quase tudo isso foi enviado para os mineradores.) -### Preparando a transação bruta +### Preparando a Transação Bruta Para as melhores práticas, iremos começar cada transação registrando cuidadosamente os txids e vouts que iremos gastar. @@ -95,23 +94,23 @@ $ echo $utxo_vout $ echo $recipient n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi ``` -Esse destinatário é particularmente importante, porque se bagunçarmos tudo, nosso dinheiro terá dado _tchau tchau_! E como já vimos, escolher a transação errada pode resultar em perda de dinheiro! Portanto, vamos verificar tudo, pelo menos uma vez mais do que a quantidade de costume. +Esse destinatário é particularmente importante, porque se bagunçarmos tudo, nosso dinheiro terá dado _tchau tchau_! E como já vimos, escolher a transação errada pode resultar em perda de dinheiro! Portanto, vamos verificar tudo, pelo menos uma vez mais do que a quantidade de costume. -### Entendendo a taxa de transação +### Entendendo a Taxa de Transação Cada transação tem uma taxa associada. Ela fica _implícita_ quando enviamos uma transação bruta: O valor que vamos pagar como taxa é sempre igual ao valor de entrada menos o valor de saída. Portanto, temos que diminuir um pouco o valor enviado para ter certeza de que nossa transação será realizada. -> :warning: **Atenção:** Esta é a parte muito perigosa das transações brutas! Como gastamos automaticamente toda a quantidade de UTXOs que tivermos, é extremamente importante certificar-se de que sabemos: (1) Precisamente quais UTXOs estamos utilizando; (2) Exatamente quanto dinheiro ele possui; (3) Exatamente quanto dinheiro estamos enviando; e (4) qual é a diferença que ficará para os mineradores. Se errarmos e, por exemplo, usarmos o UTXO errado (um que tenha mais dinheiro do que pensávamos) ou se enviarmos muito pouco dinheiro, o excesso será perdido. _Para sempre_! Não podemos cometer esse erro! Por isso, é importante sabermos as entradas e saídas com _precisão_. Ou melhor, não utilizarmos as transações brutas, exceto como parte de um programa cuidadosamente considerado e verificado três vezes. +> :warning: **ATENÇÃO:** Esta é a parte muito perigosa das transações brutas!! Como gastamos automaticamente toda a quantidade de UTXOs que tivermos, é extremamente importante certificar-se de que sabemos: (1) precisamente quais UTXOs estamos utilizando; (2) exatamente quanto dinheiro ele possui; (3) exatamente quanto dinheiro estamos enviando; e (4) qual é a diferença que ficará para os mineradores. Se errarmos e, por exemplo, usarmos o UTXO errado (um que tenha mais dinheiro do que pensávamos) ou se enviarmos muito pouco dinheiro, o excesso será perdido. _Para sempre_! Não podemos cometer esse erro! Por isso, é importante sabermos as entradas e saídas com _precisão_. Ou melhor, não utilizarmos as transações brutas, exceto como parte de um programa cuidadosamente considerado e verificado três vezes. > :book: ***Quanto devemos gastar com taxas de transação?*** [Bitcoin Fees](https://bitcoinfees.21.co/) tem uma ótima avaliação ao vivo. O site diz que "fastest and cheapest transaction fee is currently XXX satoshis/byte" onde o XXX será a quantidade de satoshis por byte que precisaremos pagar e também, "For the median transaction size of YYY bytes, this results in a fee of ZZ,ZZZ satoshis", onde YYY é o tamanho de uma transação média e ZZ,ZZZ é o resultado da multiplicação entre YYY e XXX. No caso, precisamos apenas observar o valor ZZ,ZZZ descrito no site. No momento em que este tutorial está sendo escrito, o _Bitcoin Fees_ sugere uma taxa de transação de cerca de 10.000 satoshis, que é o mesmo que 0,0001 BTC. Obviamente, isso é para a mainnet, não para a testnet, mas queremos testar as coisas de forma realista, então iremos utilizar esta quantidade. -Nesse caso, isso vamos pegar 0,0005 BTC no UTXO que selecionamos, reduzindo a quantidade de 0,0001 BTC para a taxa de transação e enviar os 0,0004 BTC restantes. E este é um exemplo do porque os micropagamentos não funcionam na rede principal do Bitcoin, porque uma taxa de transação que consome 20% do valor enviado é muito cara, agora imagina se os valores forem menores do que a taxa de transação. Por isso que temos a Lightning. +Nesse caso, isso significa que vamos pegar 0,0005 BTC no UTXO que selecionamos, reduzindo a quantidade de 0,0001 BTC para a taxa de transação e enviar os 0,0004 BTC restantes. (E este é um exemplo do porque os micropagamentos não funcionam na rede principal do Bitcoin, porque uma taxa de transação que consome 20% do valor enviado é muito cara, agora imagina se os valores forem menores do que a taxa de transação. Mas é por isso que temos a Lightning.) -> :warning: **Atenção:** Quanto menor for a taxa de transação, mais tempo irá demorar para que nossa transação entre na blockchain. O site _Bitcoin Fees_ lista os tempos que precisaremos esperar em relação a quantidade de satoshi por byte. Como os blocos são construídos em média a cada 10 minutos, a mudança de taxa pode significar uma mudança de espera de minutos para algumas horas ou dias! Portanto, escolha uma taxa de transação apropriada para o que estamos enviando. É importante observar que nunca devemos colocar taxas abaixo da quantidade mínima para transação, que é 0,0001 BTC. +> :warning: **ATENÇÃO:** Quanto menor for a taxa de transação, mais tempo irá demorar para que nossa transação entre na blockchain. O site _Bitcoin Fees_ lista os tempos que precisaremos esperar em relação a quantidade de satoshi por byte. Como os blocos são construídos em média a cada 10 minutos, a mudança de taxa pode significar uma mudança de espera de minutos para algumas horas ou dias! Portanto, escolha uma taxa de transação apropriada para o que estamos enviando. É importante observar que nunca devemos colocar taxas abaixo da quantidade mínima para transação, que é 0,0001 BTC. -### Escrevendo a transação bruta +### Escrevendo a Transação Bruta Agora estamos prontos para criar a transação bruta. Usaremos o comando ```createrawtransaction```, que pode parecer um pouco intimidante. Isso porque o comando ```createrawtransaction``` não o protege inteiramente do JSON RPC que o ```bitcoin-cli``` utiliza. Ao invés disso, vamos inserir uma matriz JSON para listar os UTXOs que está gastando e um objeto JSON para listar as saídas. @@ -138,7 +137,7 @@ $ echo $rawtxhex 02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f3610100000000ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 ``` -### Verificando a transação bruta +### Verificando a Transação Bruta Depois disso, devemos verificar a transação bruta com o comando ```decoderawtransaction``` para ter certeza de que faremos a coisa certa. ``` @@ -184,7 +183,7 @@ $ bitcoin-cli decoderawtransaction $rawtxhex > :information_source: **NOTA:** Podemos notar que cada entrada tem um número de sequência, definido aqui como 4294967295, que é 0xFFFFFFFF. Esta é a última fronteira das transações Bitcoin, porque é um campo padrão em transações que foram originalmente planejadas para um propósito específico, mas nunca foram totalmente implementadas. Portanto, agora existe esse inteiro parado em transações que podem ser reaproveitadas para outros usos. E, de fato, tem sido. No momento em que este livro foi escrito, havia três usos diferentes para a variável chamada ```nSequence``` no código Bitcoin Core: Ela habilita a possibilidade de RBF, ```nLockTime``` e timelocks relativos. Se não houver nada de estranho acontecendo, o ```nSequence``` será definido como 4294967295. Ajustar para um valor mais baixo sinaliza que coisas especiais estão acontecendo. -### Assinando a transação bruta +### Assinando a Transação Bruta Até o momento, nossa transação bruta é apenas uma teoria: _Podemos_ enviá-la, mas nada irá acontecer. Precisamos fazer algumas coisas para colocá-la na rede. @@ -200,7 +199,7 @@ $ signedtx="02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01 ``` Observe que capturamos o hexadecimal assinado manualmente, ao invés de tentar analisá-lo a partir do objeto JSON. Um pacote de software chamado "JQ" poderia ter um desempenho melhor, como explicaremos no próximo prefácio. -### Enviando a transação bruta +### Enviando a Transação Bruta Agora temos uma transação bruta pronta para ser usada, mas nada acontece com ela se não a colocarmos na rede, o que iremos fazer com o comando ```sendrawtransaction```. O retorno dele será uma txid: ``` @@ -261,14 +260,14 @@ Logo o ```listtransactions``` deve mostrar uma transação confirmada da categor "abandoned": false } ``` -Podemos observar que ele corresponde aos endereços ```txid``` e ```recipient``` (recebedor). Não só mostra o ```amount``` (montante) enviado, mas também mostra a ```fee``` (taxa) da transação. E, a transação já recebeu uma confirmação, porque oferecemos uma taxa que seria colocado no próximo bloco. +Podemos observar que ele corresponde aos endereços ```txid``` e ```recipient``` (recebedor). Não só mostra o ```amount``` (montante) enviado, mas também mostra a ```fee``` (taxa) da transação. E, a transação já recebeu uma confirmação, porque oferecemos uma taxa que a faria ser colocada em um bloco rapidamente. Parabéns! Estamos um pouco mais pobres agora! -## Resumo do Criando uma transação bruta +## Resumo: Criando uma Transação Bruta -Quando satoshinhos entram na nossa carteira Bitcoin, eles permanecem em quantidades distintas, chamadas de UTXOs. Ao criar uma transação bruta para enviar as moedas, usamos um ou mais UTXOs para financiá-la. Podemos então, criar uma transação bruta, assiná-la e enviá-la pela rede Bitcoin. No entanto, esta é apenas uma base do que realmente acontece: Geralmente precisaremos criar uma transação bruta com várias saídas para realmente enviar algo na rede Bitcoin! +Quando satoshinhos entram na nossa carteira Bitcoin, eles permanecem em quantidades distintas, chamadas de UTXOs. Ao criar uma transação bruta para enviar as moedas, usamos um ou mais UTXOs para financiá-la. Podemos então, criar uma transação bruta, assiná-la e enviá-la pela rede Bitcoin. No entanto, esta é apenas uma base do que realmente acontece: geralmente precisaremos criar uma transação bruta com várias saídas para realmente enviar algo na rede Bitcoin! -## O que vem depois? +## O Que Vem Depois? -Vamos fazer uma pausa do "Enviando transações de Bitcoin" para lermos o [Interlúdio: Usando JQ](04_2__Interlude_Using_JQ.md). \ No newline at end of file +Vamos fazer uma pausa do "Enviando Transações no Bitcoin" para lermos o [Prefácio: Usando JQ](04_2__Interlude_Using_JQ.md). \ No newline at end of file From b0e25e7a8e7d8595f5d7def7830935855e0aa6ea Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 17:39:32 -0300 Subject: [PATCH 40/50] Review 04_2__Interlude --- pt/04_2__Interlude_Using_JQ.md | 110 ++++++++++++++++----------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/pt/04_2__Interlude_Using_JQ.md b/pt/04_2__Interlude_Using_JQ.md index 00b46cf..0ec4618 100644 --- a/pt/04_2__Interlude_Using_JQ.md +++ b/pt/04_2__Interlude_Using_JQ.md @@ -1,8 +1,8 @@ -# Prefácio: Usando o JQ +# Prefácio: Usando JQ -A criação de uma transação bruta revelou como resultados mais complexos do ```bitcoin-cli``` que não podem ser salvos facilmente em variáveis de linha de comando. A resposta para isso e usar o JQ, que permite filtrar elementos individuais de dados JSON mais complexos. +A criação de uma transação bruta revelou como resultados mais complexos do ```bitcoin-cli``` não podem ser salvos facilmente em variáveis de linha de comando. A resposta para isso é usar o JQ, que permite filtrar elementos individuais de dados JSON mais complexos. -## Instalando o JQ +## Instalando JQ O JQ está disponível em um [repositório no Github](https://stedolan.github.io/jq/). Basta fazermos o download para Linux, OS X ou Windows, de acordo com o seu sistema operacional. @@ -11,11 +11,11 @@ Depois de baixar o binário, podemos instalá-lo em nosso sistema. Se estivermos $ mv jq-linux64 jq $ sudo /usr/bin/install -m 0755 -o root -g root -t /usr/local/bin jq ``` -> :book: ***O que é o JQ?*** O repositório explica melhor, dizendo "O jq é como o sed para dados o JSON - você pode usá-lo para dividir, filtrar, mapear e transformar dados estruturados com a mesma facilidade que o sed, awk, grep e permitem que você brinque com o texto". +> :book: ***O que é JQ?*** O repositório explica melhor, dizendo "O jq é como o sed para dados JSON - você pode usá-lo para dividir, filtrar, mapear e transformar dados estruturados com a mesma facilidade que o sed, awk, e grep permitem que você brinque com o texto". -## Usando o JQ para acessar um valor do objeto JSON pelo índice +## Usando JQ Para Acessar o Valor de um Objeto JSON Pelo Índice -**Caso de uso:** _Capturando o hex de uma transação bruta assinada._ +**Caso de Uso:** _Capturando o hex de uma transação bruta assinada._ Na seção anterior, o uso de ```signrawtransaction``` não pareceu ser um bom método devido ao fato de não ser capaz de capturar os dados facilmente em variáveis devido a seu retorno no formato JSON: ``` @@ -27,14 +27,14 @@ $ bitcoin-cli signrawtransactionwithwallet $rawtxhex ``` Felizmente, o JQ pode facilmente capturar os dados desse tipo! -Para usar o JQ, vamos executar ```jq``` no backend de um pipe e sempre usar a invocação padrão que é ```jq -r '.'```. O ```-r``` diz ao JQ para diminuir a saída bruta, que funcionará para variáveis de linha de comando, enquanto o ```.``` diz ao JQ para mostrar na tela Protegemos esse argumento com ```''``` porque precisaremos dessa proteção mais tarde conforme nossas invocações ```JQ``` se tornarem mais complexas. +Para usar o JQ, vamos executar ```jq``` no backend de um pipe e sempre usar a invocação padrão que é ```jq -r '.'```. O ```-r``` diz ao JQ para produzir uma saída bruta, que funcionará para variáveis de linha de comando, enquanto o ```.``` diz ao JQ para mostrar na tela. Protegemos esse argumento com ```' '``` porque precisaremos dessa proteção mais tarde conforme nossas invocações ```jq``` se tornarem mais complexas. Para capturar um valor específico de um objeto JSON, basta listar o índice após o ```.```: ``` $ bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex' 02000000013a6e4279b799791049e1826602e84d2e36797e2005887b98c3ecf16b01b7f361010000006a4730440220335d15a2a2ca3ce6a302ce041686739d4a38eb0599a5ea08305de71965268d05022015f77a33cf7d613015b2aba5beb03088033625505ad5d4d0624defdbea22262b01210278608b54b8fb0d8379d3823d31f03a7c6ab0adffb07dd3811819fdfc34f8c132ffffffff01409c0000000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000 ``` -Com essa ferramenta em mãos, podemos capturar as informações dos objetos JSON para variáveis na linha de comando: +Com essa ferramenta em mãos, podemos capturar as informações de objetos JSON para variáveis na linha de comando: ``` $ signedtx=$(bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex') $ echo $signedtx @@ -45,13 +45,13 @@ Podemos usar então essas variáveis facilmente e sem erros: $ bitcoin-cli sendrawtransaction $signedtx 3f9ccb6e16663e66dc119de1866610cc4f7a83079bfec2abf0598ed3adf10a78 ``` -## Usando o JQ para acessar valores únicos do objeto JSON em um array usando o índice +## Usando JQ Para Acessar Valores Únicos de um Objeto JSON em um Array Pelo Índice -**Caso de uso:** _Capturando o txid e o vout para um UTXO selecionado._ +**Caso de Uso:** _Capturando o txid e o vout para um UTXO selecionado._ -Extrair dados de um objeto JSON é fácil, mas e se esse objeto JSON estiver em uma matriz JSON? O comando ```listunspent``` oferece um ótimo exemplo, porque geralmente contém várias transações diferentes. E se quisermos capturar as informações específicas de _um_ deles? +Extrair dados de um objeto JSON é fácil, mas e se esse objeto JSON estiver em um array JSON? O comando ```listunspent``` oferece um ótimo exemplo, porque geralmente contém várias transações diferentes. E se quisermos capturar as informações específicas de _um_ deles? -Ao trabalhar com um array JSON, a primeira coisa que precisamos fazer é informar ao JQ qual índice acessar. Por exemplo, podemos estar olhando nossas transações no ```listunspent``` e decidimos que queremos trabalhar com a segunda. Podemos usar o ```'. [1]'``` para acessar o primeiro elemento. O ```[]``` diz que estamos referenciando um array JSON e o ```0``` diz que queremos o índice 0. +Ao trabalhar com um array JSON, a primeira coisa que precisamos fazer é informar ao JQ qual índice acessar. Por exemplo, podemos estar olhando nosswas transações no ```listunspent``` e decidimos que queremos trabalhar com a segunda. Podemos usar o ```'. [1]'``` para acessar o primeiro elemento. O ```[]``` diz que estamos referenciando um array JSON e o ```0``` diz que queremos o índice 0. ``` $ bitcoin-cli listunspent | jq -r '.[1]' { @@ -68,12 +68,12 @@ $ bitcoin-cli listunspent | jq -r '.[1]' "safe": true } ``` -Podemos então capturar um valor individual dessa matriz (1) selecionada usando um pipe _dentro_ dos argumentos JQ; e então o (2) solicitando o valor específico posteriormente, como no exemplo anterior. Isso iria capturar o ```txid``` do primeiro objeto JSON na matriz JSON produzida pelo comando ```listunspent```: +Podemos então capturar um valor individual desse array selecionado (1) usando um pipe _dentro_ dos argumentos JQ; e então (2) solicitando o valor específico posteriormente, como no exemplo anterior. Isso iria capturar o ```txid``` do primeiro objeto JSON no array JSON produzido pelo comando ```listunspent```: ``` $ bitcoin-cli listunspent | jq -r '.[1] | .txid' 91261eafae15ea53dedbea7c1db748c52bbc04a85859ffd0d839bda1421fda4c ``` -Observe cuidadosamente como os ```''``` circundam toda a expressão JQ _incluindo_ o pipe. +Observe cuidadosamente como os ```' '``` circundam toda a expressão JQ _incluindo_ o pipe. Este método pode ser usado para preencher variáveis para um UTXO que desejamos utilizar: ``` @@ -86,20 +86,20 @@ $ echo $newvout ``` Pronto! Agora podemos criar uma nova transação bruta usando nosso primeiro UTXO como entrada, sem ter que digitar qualquer uma das informações do UTXO manualmente! -## Usando o JQ para acessar valores dos objetos JSON correspondentes em um array usando os índices +## Usando JQ Para Acessar Valores de Objetos JSON Correspondentes em um Array Por Índices -**Caso de uso:** _Listar o valor de todos os UTXOs._ +**Caso de Uso:** _Listar o valor de todos os UTXOs._ -Ao invés de acessar um único valor específico em um objeto JSON específico, podemos acessar todos os valores específicos em todos os objetos JSON. Isso é feito com ```. []```, Onde nenhum índice é especificado. Por exemplo, podemos listar todos os saldos não gastos: +Ao invés de acessar um único valor específico em um objeto JSON específico, podemos acessar todos os valores específicos em todos os objetos JSON. Isso é feito com ```.[]```, Onde nenhum índice é especificado. Por exemplo, podemos listar todos os saldos não gastos: ``` $ bitcoin-cli listunspent | jq -r '.[] | .amount' 0.0001 0.00022 ``` -## Usando o JQ para cálculos simples usando índices +## Usando JQ Para Cálculos Simples Por Índices -**Caso de uso:** _Adicionando o valor de todos os UTXOs não gastos._ +**Caso de Uso:** _Adicionando o valor de todos os UTXOs não gastos._ Neste ponto, podemos começar a usar o retorno do JQ para fazermos uma matemática simples. Por exemplo, somar os valores dessas transações não gastas com um script ```awk``` simples nos daria o equivalente ao ```getbalance```: ``` @@ -109,13 +109,13 @@ $ bitcoin-cli getbalance 0.00032000 ``` -## Usando o JQ para exibir vários valores de um objeto JSON em um array usando vários índice +## Usando JQ Para Exibir Vários Valores de um Objeto JSON em um Array Por Vários Índices -**Caso de uso:** _Listar as informações de uso para todos os UTXOs._ +**Caso de Uso:** _Listar as informações de uso para todos os UTXOs._ O JQ pode capturar facilmente elementos individuais de objetos JSON e arrays e colocar os elementos em variáveis. Esse será o principal uso que iremos fazer nas seções futuras. No entanto, ele também pode ser usado para reduzir grandes quantidades de informações geradas pelo ```bitcoin-cli``` em quantidades razoáveis de informações. -Por exemplo, podemos querer ver uma lista de todos os nossos UTXOs (```. []```) E obter uma lista de todas as informações mais importantes (```.txid, .vout, .amount```): +Por exemplo, podemos querer ver uma lista de todos os nossos UTXOs (```.[]```) E obter uma lista de todas as informações mais importantes (```.txid, .vout, .amount```): ``` $ bitcoin-cli listunspent | jq -r '.[] | .txid, .vout, .amount' ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36 @@ -127,7 +127,7 @@ ca4898d8f950df03d6bfaa00578bd0305d041d24788b630d0c4a32debcac9f36 ``` Isso torna mais fácil decidir quais UTXOs gastar em uma transação bruta, mas não é muito bonito. -Felizmente, o JQ também permite que sejamos mais sofisticados. Podemos usar as ```{}``` para criar novos objetos JSON (para análise adicional ou para um retorno mais bonito). Também podemos definir o nome da nova chave para cada um dos valores. A saída resultante deve ser muito mais intuitiva e menos sujeita a erros (embora, menos útil para jogar as informações diretamente nas variáveis). +Felizmente, o JQ também permite que sejamos mais sofisticados. Podemos usar as ```{}``` para criar novos objetos JSON (para análise adicional ou para um retorno mais bonito). Também podemos definir o nome do novo índice para cada um dos valores. A saída resultante deve ser muito mais intuitiva e menos sujeita a erros (embora, menos útil para jogar as informações diretamente nas variáveis). O exemplo a seguir mostra exatamente a mesma análise do ```listunspent```, mas com cada objeto JSON antigo reconstruído como um novo objeto JSON abreviado, com todos os novos valores nomeados com os índices antigos: ``` @@ -157,13 +157,13 @@ $ bitcoin-cli listunspent | jq -r '.[] | { tx: .txid, output: .vout, bitcoins: . "bitcoins": 0.00022 } ``` -## Usando o JQ para acessar os objetos JSON usando um valor pesquisado +## Usando JQ Para Acessar Objetos JSON Por Valor Pesquisado -**Caso de uso:** _Pesquisando automaticamente os UTXOs que estão sendo usados em uma transação._ +**Caso de Uso:** _Pesquisando automaticamente os UTXOs que estão sendo usados em uma transação._ -As pesquisas JQ até agora são bastante simples: Usamos um índice para pesquisar um ou mais valores em um objeto JSON ou no array. Mas e se quisermos pesquisar um valor em um objeto JSON... usando outro valor? Esse tipo de pesquisa indireta tem aplicabilidade real quando estamos trabalhando com transações criadas usando as UTXOs existentes. Por exemplo, podemos calcular o valor da soma dos UTXOs sendo usados em uma transação, algo de vital importância. +As pesquisas JQ até agora têm sido bastante simples: Usamos um índice para pesquisar um ou mais valores em um objeto JSON ou no array. Mas e se quisermos pesquisar um valor em um objeto JSON... usando outro valor? Esse tipo de pesquisa indireta tem aplicabilidade real quando estamos trabalhando com transações criadas usando os UTXOs existentes. Por exemplo, podemos calcular o valor da soma dos UTXOs sendo usados em uma transação, algo de vital importância. -Este exemplo usa a seguinte transação bruta. Podemos observar que esta é uma transação bruta mais complexa com duas entradas e duas saídas. Aprenderemos como fazer isso nas próximas sessões, mas por enquanto, é necessário sermos capazes de oferecer exemplos robustos. Observe que, ao contrário dos nossos exemplos anteriores, neste, temos dois objetos em nosso array ```vin``` e dois em nosso array ```vout```. +Este exemplo usa a seguinte transação bruta. Podemos observar que esta é uma transação bruta mais complexa com duas entradas e duas saídas. Aprenderemos como fazer isso nas próximas seções, mas por enquanto, é necessário sermos capazes de oferecer exemplos robustos. Observe que, ao contrário dos nossos exemplos anteriores, neste, temos dois objetos em nosso array ```vin``` e dois em nosso array ```vout```. ``` $ bitcoin-cli decoderawtransaction $rawtxhex { @@ -224,9 +224,9 @@ $ bitcoin-cli decoderawtransaction $rawtxhex } ``` -### Recuperando o(s) valor(es) +### Recuperando Valor(es) -Suponha que saibamos exatamente como essa transação é construída: Sabemos que ela usa dois UTXOs como entrada. Para recuperar o txid para os dois UTXOs, poderíamos usar ```jq``` para consultar o valor .vin da transação e, em seguida, fazer referência ao primeiro índice do .vin e, em seguida, ao valor .txid desse array. Posteriormente, poderíamos fazer o mesmo com o primeiro array e, em seguida, o mesmo com os dois valores .vout de .vin. Simples: +Suponha que saibamos exatamente como essa transação é construída: sabemos que ela usa dois UTXOs como entrada. Para recuperar o txid para os dois UTXOs, poderíamos usar ```jq``` para consultar o valor .vin da transação e, em seguida, fazer referência ao primeiro índice do .vin e, então, ao valor .txid deste array. Posteriormente, poderíamos fazer o mesmo com o primeiro array e, em seguida, o mesmo com os dois valores .vout de .vin. Fácil: ``` $ usedtxid1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .txid') $ echo $usedtxid1 @@ -244,7 +244,7 @@ $ echo $usedvout2 ``` No entanto, seria melhor ter um caso geral que salvasse _automaticamente_ todos os txids de nossos UTXOs. -Já sabemos que podemos acessar todos os ```.txid``` usando um valor do array ```. [] ```. Podemos usar isso para criar uma pesquisa geral no .txid: +Já sabemos que podemos acessar todos os ```.txid``` usando um valor do array ```.[] ```. Podemos usar isso para criar uma pesquisa geral no .txid: ``` $ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid')) $ echo ${usedtxid[0]} @@ -258,13 +258,13 @@ $ echo ${usedvout[0]} $ echo ${usedvout[1]} 1 ``` -O único truque real aqui é como salvamos as informações usando o shell bash. Ao invés de salvar em uma variável com ```$ (command)```, nós salvamos em um array com ```($ (command))```. Fomos então capazes de acessar os elementos individuais do array bash com uma construção ```$ {variable [n]}```. Ao invés disso, poderíamos acessar todo o array usando a ```$ {variable [@]}```. (E antes que diga algo, ninguém nunca disse que o bash ficaria bonito). +O único truque real aqui é como salvamos as informações usando o shell bash. Ao invés de salvar em uma variável com ```$(command)```, nós salvamos em um array com ```($(command))```. Fomos então capazes de acessar os elementos individuais do array bash com uma construção ```${variable [n]}```. Ao invés disso, poderíamos acessar todo o array usando a ```${variable [@]}```. (E antes que diga algo, ninguém nunca disse que o bash ficaria bonito). > :warning: **ATENÇÃO:** Lembre-se sempre de que um UTXO é uma transação _mais_ um vout. Perdemos o vout na primeira vez que escrevemos este exemplo JQ, e ele parou de funcionar quando acabamos com uma situação em que dois ```vouts``` foram enviados da mesma transação. -### Recuperando o(s) objeto(s) relacionado(s) +### Recuperando o(s) Objeto(s) Relacionado(s) -Agora podemos usar as informações salvas no ```txid``` e no ```vout``` para referenciar os UTXOs no ```listunspent```. Para encontrar as informações sobre os UTXOs usados pela transação bruta, precisamos examinar todo o array JSON (```[]```) com as transações não gastas. Podemos então escolher (```select```) objetos JSON individuais que incluem (```contains```) os txids. _Então_ selecionamos (```select```) as transações entre aquelas que _também_ contém (```contêm```) o valor correto. +Agora podemos usar as informações salvas no ```txid``` e no ```vout``` para referenciar os UTXOs no ```listunspent```. Para encontrar as informações sobre os UTXOs usados pela transação bruta, precisamos examinar todo o array JSON (```[]```) com as transações não-gastas. Podemos então escolher (```select```) objetos JSON individuais que incluam (```contains```) os txids. _Então_ selecionamos (```select```) as transações entre aquelas que _também_ contêm (```contain```) o valor correto. O uso de outro nível do pipe é a metodologia padrão do JQ: Pegamos um conjunto de dados, depois a reduzimos para todas as transações relevantes e, em seguida, reduzimos para os valores que foram realmente usados nessas transações. No entanto, os argumentos ```select``` e ```contains``` são algo novo. Eles mostram um pouco da complexidade do JSON que vai além do escopo deste tutorial. Por enquanto, saiba apenas que esta invocação em particular funcionará para capturar objetos correspondentes. @@ -293,7 +293,7 @@ $ bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${usedtxid[1 "solvable": true } ``` -Ao invés disso, um simples bash usando um loop em ```for``` poderia nos dar _todos_ os nossos UTXOs: +Ao invés disso, um simples bash usando um loop ```for``` poderia nos dar _todos_ os nossos UTXOs: ``` $ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout'))'; done; { @@ -318,13 +318,13 @@ $ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i } ``` -Observe que estamos deixando um pouquinho mais feio nosso array ```$ {# usedtxid [*]}``` para determinar o tamanho dele, em seguida, acessamos cada valor no array ```usedtxid``` e cada valor no array ```usedvout``` paralelo, os colocando em variáveis mais simples para termos um acesso menos feio. +Observe que estamos deixando um pouquinho mais feio nosso array ```${#usedtxid[*]}``` para determinar o tamanho dele e, em seguida, acessamos cada valor no array ```usedtxid``` e cada valor no array ```usedvout``` em paralelo, colocando-os em variáveis mais simples para termos um acesso menos feio. -## Usando o JSON para cálculos simples usando os valores +## Usando JSON Para Cálculos Simples Por Valor -**Caso de uso:** _Calcular automaticamente o valor dos UTXOs usados em uma transação._ +**Caso de Uso:** _Calcular automaticamente o valor dos UTXOs usados em uma transação._ -Agora podemos ir um passo adiante e solicitar o .amount (ou qualquer outro valor do índice do JSON) dos UTXOs que estamos recuperando. +Agora podemos ir um passo adiante e solicitar o .amount (ou qualquer outro par índice-valor do JSON) dos UTXOs que estamos recuperando. Este exemplo repete o uso dos arrays ```$usedtxid``` e ```$usedvout``` definidos da seguinte forma: @@ -348,13 +348,13 @@ $ for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i 1.3 ``` -Perfeito! +Ufa! -## Usando o JQ para cálculos complexos +## Usando JQ Para Cálculos Complexos -**Caso de uso:** _Calcular a taxa de uma transação._ +**Caso de Uso:** _Calcular a taxa de uma transação._ -Descobrir a taxa de transação completa neste ponto requer apenas mais um pouco de matemática: Bastando determinar quanto dinheiro está passando pelo .vout. Este é um uso simples de JQ onde apenas usamos o ```awk``` para somar o ```valor``` de todas as informações do ```vout```: +Descobrir a taxa completa de transação neste ponto requer apenas mais um pouco de matemática: basta determinar quanto dinheiro está passando pelo .vout. Este é um uso simples de JQ onde apenas usamos o ```awk``` para somar o ```value``` de todas as informações do ```vout```: ``` $ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk '{s+=$1} END {print s}' @@ -362,7 +362,7 @@ $ bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout [] | .value' | awk ``` Para completar o cálculo da taxa de transação, vamos subtrair o .vout .amount (1.045) do .vin .amount (1.3). -Para fazer isso, precisaremos instalar o ```bc```: +Para fazer isso, precisaremos instalar ```bc```: ``` $ sudo apt-get intall bc @@ -379,15 +379,15 @@ $ echo "$btcin-$btcout"| /usr/bin/bc .255 ``` -E esse também é um bom exemplo de por que precisamos verificar nossas suas taxas: Pretendíamos enviar uma taxa de transação com 5.000 satoshis, mas invés disso enviamos pagando 255.000 satoshis de taxa. Ops! +E esse também é um bom exemplo de por que precisamos verificar nossas taxas: pretendíamos enviar uma taxa de transação com 5.000 satoshis, mas invés disso enviamos pagando 255.000 satoshis de taxa. Ops! -> :warning: **Atenção:** A primeira vez que escrevemos esta lição, realmente calculamos mal a nossa taxa e não a vimos até que executamos nossa calculadora de taxas. É *tão* fácil, que nosso dinheiro acabou. (O exemplo acima é, na verdade, de nossa segunda iteração da calculadora, e dessa vez cometemos o erro de propósito). +> :warning: **ATENÇÃO:** A primeira vez que escrevemos esta lição, realmente calculamos mal a nossa taxa e não a vimos até que executamos nossa calculadora de taxas. É *tão* fácil, que nosso dinheiro acabou. (O exemplo acima é, na verdade, de nossa segunda iteração da calculadora, e dessa vez cometemos o erro de propósito). -Para mais magia usando o JSON (e se alguma coisa não estiver clara), leia o [Manual JSON](https://stedolan.github.io/jq/manual/) e o [Livro de Receitas do JSON](https://github.com/stedolan/jq/wiki/Cookbook). Estaremos usando o JQ regularmente nos exemplos futuros. +Para mais magia usando o JQ (e se alguma coisa não estiver clara), leia o [Manual JQ](https://stedolan.github.io/jq/manual/) e o [Livro de Receitas do JQ](https://github.com/stedolan/jq/wiki/Cookbook). Estaremos usando o JQ regularmente nos exemplos futuros. -## Fazendo alguns aliases novos +## Fazendo Alguns Aliases Novos -O código JQ pode ser um pouco pesado, então devemos considerar adicionar algumas invocações mais longas e interessantes ao nosso ```~/.bash_profile```. +Código em JQ pode ser um pouco pesado, então devemos considerar adicionar algumas invocações mais longas e interessantes ao nosso ```~/.bash_profile```. Sempre que estivermos procurando por uma grande massa de informações em uma saída de objeto JSON por um comando ```bitcoin-cli```, precisamos considerar escrever um alias para reduzi-lo exatamente ao que desejamos observar. @@ -395,11 +395,11 @@ Sempre que estivermos procurando por uma grande massa de informações em uma sa alias btcunspent="bitcoin-cli listunspent | jq -r '.[] | { txid: .txid, vout: .vout, amount: .amount }'" ``` -## Executando o script de taxa de transação +## Executando o Script de Taxa de Transação -O [script de cálculo de taxa](src/04_2_i_txfee-calc.sh) está disponível no diretório src/. Você pode baixá-lo e salvá-lo como ```txfee-calc.sh```. +O [Script de Cálculo de Taxa](src/04_2_i_txfee-calc.sh) está disponível no diretório `src/`. Você pode baixá-lo e salvá-lo como ```txfee-calc.sh```. -> :warning: **Atenção:** Este script não foi verificado extensivamente. Se for usá-lo para verificar as taxas de transação reais, só deve fazê-lo depois de fazer uma verificação pessoal dos valores. +> :warning: **ATENÇÃO:** Este script não foi verificado extensivamente. Se for usá-lo para verificar as taxas de transação reais, só deve fazê-lo depois de fazer uma verificação pessoal dos valores. Certifique-se de que as permissões no script estejam corretas: @@ -407,7 +407,7 @@ Certifique-se de que as permissões no script estejam corretas: $ chmod 755 txfee-calc.sh ``` -Podemos então, executar o script da seguinte maneira: +Podemos, então, executar o script da seguinte maneira: ``` $ ./txfee-calc.sh $rawtxhex @@ -420,10 +420,10 @@ Também podemos criar um alias: alias btctxfee="~/txfee-calc.sh" ``` -## Resumo do Usando o JQ +## Resumo: Usando JQ O JQ facilita a extração de informações de arrays e objetos JSON. Ele também pode ser usado em scripts shell para cálculos bastante complexos que tornarão nossa vida mais fácil. -## O que vem depois? +## O Que Vem Depois? -Continue "Enviando Transações de Bitcoin" na sessão [§4.3 Criando uma transação bruta com argumentos nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md). \ No newline at end of file +Continue "Enviando Transações no Bitcoin" na sessão [§4.3 Criando uma Transação Bruta com Argumentos Nomeados](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md). \ No newline at end of file From cac5dbc2435959eee629605cb85834474cd30d87 Mon Sep 17 00:00:00 2001 From: namcios Date: Wed, 30 Jun 2021 17:45:31 -0300 Subject: [PATCH 41/50] Review 04_3 --- ..._a_Raw_Transaction_with_Named_Arguments.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md b/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md index 2ff9957..529b821 100644 --- a/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md +++ b/pt/04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md @@ -1,10 +1,10 @@ -# 4.3 Criando uma transação bruta com argumentos nomeados +# 4.3 Criando uma Transação Bruta com Argumentos Nomeados -Às vezes, pode ser assustador descobrir a ordem correta dos argumentos para um comando ```bitcoin-cli```. Felizmente, podemos usar _ argumentos nomeados_ como alternativa. +Às vezes, pode ser assustador descobrir a ordem correta dos argumentos para um comando ```bitcoin-cli```. Felizmente, podemos usar _argumentos nomeados_ como alternativa. > :warning: **AVISO DE VERSÃO:** Esta é uma inovação do Bitcoin Core v0.14.0. Se usarmos os scripts de configuração do tutorial, o que é importante fazer, precisamos verificar novamente a versão se tiver algum problema. Há também um bug no uso do comando ```createrawtransaction``` usando argumentos nomeados que presumivelmente serão corrigidos na versão 0.14.1. -## Criando um alias do argumento nomeado +## Criando um Alias de Argumento Nomeado Para usar um argumento nomeado, devemos executar o ```bitcoin-cli``` com o argumento ```-named```. Se planejamos fazer isso regularmente, provavelmente precisaremos criar um alias: ``` @@ -12,7 +12,7 @@ alias bitcoin-cli="bitcoin-cli -named" ``` Como de costume, isso é apenas para facilitar o uso, mas continuaremos usando todos os comandos para manter a clareza. -## Testando um argumento nomeado +## Testando um Argumento Nomeado Para saber quais são os nomes dos argumentos de um comando, precisamos consultar o ```bitcoin-cli help```. Ele listará os argumentos com a ordem adequada, mas agora também fornecerá nomes para cada um deles. @@ -32,7 +32,7 @@ Com argumentos nomeados, podemos esclarecer o que estamos fazendo, o que também $ bitcoin-cli -named getbalance minconf=1 ``` -## Testando uma transação bruta +## Testando uma Transação Bruta Veja como seriam os comandos para enviar uma transação bruta com argumentos nomeados: ``` @@ -82,16 +82,16 @@ $ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx e70dd2aa13422d12c222481c17ca21a57071f92ff86bdcffd7eaca71772ba172 ``` -Pronto! Enviamos outra transação bruta, mas desta vez usando argumentos nomeados para ter maior clareza e redução de erros. +Pronto! Enviamos outra transação bruta, mas desta vez usando argumentos nomeados para maior clareza e redução de erros. -> :warning: **AVISO DE VERSÃO:** É aqui que o bug no Bitcoin Core 0.14 aparece: O argumento ```inputs``` no ```createrawtransaction``` tem o nome ```transactions``` incorreto. Portanto, se estivermos no Bitcoin Core 0.14.0, substitua o argumento nomeado ```inputs``` por ```transactions``` para este e também para os exemplos futuros. No entanto, a partir do Bitcoin Core 0.14.1, esse código deve funcionar normalmente. +> :warning: **AVISO DE VERSÃO:** É aqui que o bug no Bitcoin Core 0.14 aparece: O argumento ```inputs``` no ```createrawtransaction``` tem o nome ```transactions``` incorreto. Portanto, se estiver no Bitcoin Core 0.14.0, substitua o argumento nomeado ```inputs``` por ```transactions``` para este e também para os exemplos futuros. No entanto, a partir do Bitcoin Core 0.14.1, este código deve funcionar normalmente. -## Resumo do Criando uma transação bruta com argumentos nomeados +## Resumo: Criando uma Transação Bruta com Argumentos Nomeados -Executando o ```bitcoin-cli``` com o argumento ```-named```, podemos usar argumentos nomeados ao invés de depender de argumentos ordenados. O comando ```bitcoin-cli help``` sempre mostrará o nome correto para cada argumento. Isso pode resultar em um código mais robusto, mais fácil de ler e menos sujeito a erros. +Executando o ```bitcoin-cli``` com o argumento ```-named``` podemos usar argumentos nomeados ao invés de depender de argumentos ordenados. O comando ```bitcoin-cli help``` sempre mostrará o nome correto para cada argumento. Isso pode resultar em um código mais robusto, mais fácil de ler e menos sujeito a erros. -_À partir de agora, usaremos argumentos nomeados para todos os exemplos futuros, para maior clareza e para estabelecer as melhores práticas. No entanto, também mostraremos todos os argumentos na ordem correta. Portanto, se preferir não usar os argumentos nomeados, apenas retire o argumento ```-named``` e todos os ```name =``` que os exemplos devem continuar funcionando corretamente._ +_À partir de agora, usaremos argumentos nomeados para todos os exemplos futuros, para maior clareza e para estabelecer as melhores práticas. No entanto, também mostraremos todos os argumentos na ordem correta. Portanto, se preferir não usar os argumentos nomeados, apenas retire o argumento ```-named``` e todos os ```name=``` que os exemplos devem continuar funcionando corretamente._ -## O que vem depois? +## O Que Vem Depois? -Continue "Enviando Transações de Bitcoin" na sessão [§4.4: Enviando bitcoins usando transações brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md). \ No newline at end of file +Continue "Enviando Transações no Bitcoin" na seção [§4.4: Enviando Moedas com Transações Brutas](04_4_Sending_Coins_with_a_Raw_Transaction.md). \ No newline at end of file From eb78a37ffc822865e60b69254e3f869d4bd99f80 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 1 Jul 2021 11:35:29 -0300 Subject: [PATCH 42/50] Review 04_4 --- ..._4_Sending_Coins_with_a_Raw_Transaction.md | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md index 5a3b40e..d9d8ca9 100644 --- a/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md +++ b/pt/04_4_Sending_Coins_with_a_Raw_Transaction.md @@ -1,32 +1,32 @@ -# 4.4: Enviando bitcoins usando transações brutas +# 4.4: Enviando Moedas com Transações Brutas -Conforme observado no início deste capítulo, a interface ```bitcoin-cli``` oferece três maneiras principais de enviar moedas. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) falou sobre como enviá-la pela primeira vez, usando o comando ```sendtoaddress```. Desde então, estamos construindo coisas mais detalhadas sobre como enviar moedas de uma segunda maneira, com transações brutas. A sessão [§4.2](04_2_Creating_a_Raw_Transaction.md) nos ensinou como criar uma transação bruta, um [Prefácio](04_2__Interlude_Using_JQ.md) explicou sobre o JQ e a sessão [§4.3](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) demonstrou os argumentos nomeados. +Conforme observado no início deste capítulo, a interface ```bitcoin-cli``` oferece três maneiras principais de enviar moedas. A seção [§4.1](04_1_Sending_Coins_The_Easy_Way.md) falou sobre como enviá-la pela primeira vez, usando o comando ```sendtoaddress```. Desde então, estamos construindo coisas mais detalhadas sobre como enviar moedas de uma segunda maneira, com transações brutas. A seção [§4.2](04_2_Creating_a_Raw_Transaction.md) nos ensinou como criar uma transação bruta, um [Prefácio](04_2__Interlude_Using_JQ.md) explicou JQ e a seção [§4.3](04_3_Creating_a_Raw_Transaction_with_Named_Arguments.md) demonstrou os argumentos nomeados. Agora podemos colocá-los juntos e realmente enviar fundos usando uma transação bruta. -## Criando uma endereço de troco +## Criando um Endereço de Troco -Nosso exemplo de transação bruta na seção §4.2 era simples demais: Enviamos um UTXO inteiro para um novo endereço. Com mais frequência, iremos desejar enviar a alguém uma quantia em dinheiro que não corresponde a um UTXO. Mas, devemos nos lembrar que o excesso de dinheiro de um UTXO que não é enviado ao destinatário se torna apenas a taxa de transação. Então, como enviar para alguém apenas uma parte de um UTXO, enquanto guardamos o resto pra gente? +Nosso exemplo de transação bruta na seção §4.2 era simples demais: enviamos um UTXO inteiro para um novo endereço. Com mais frequência, iremos desejar enviar a alguém uma quantia em dinheiro que não corresponda a um UTXO. Mas, devemos nos lembrar que o excesso de dinheiro de um UTXO que não é enviado ao destinatário se torna apenas a taxa de transação. Então, como enviar para alguém apenas uma parte de um UTXO, enquanto guardamos o resto para a gente? -A solução é _enviar_ o restante dos fundos para um segundo endereço, um endereço de troco que criamos em nossa carteira especificamente para recebê-los: +A solução é _enviar_ o restante dos fundos para um segundo endereço, um endereço de troco que criamos em nossa carteira especificamente para recebê-lo: ``` $ changeaddress=$(bitcoin-cli getrawchangeaddress legacy) $ echo $changeaddress mk9ry5VVy8mrA8SygxSQQUDNSSXyGFot6h ``` -Observe que isso usa uma nova função: ```getrawchangeaddress```. É basicamente é a mesma coisa que o ```getnewaddress```, mas é otimizado para uso como um endereço de truco em uma transação bruta, portanto, não faz coisas como criar entradas em nossa lista de endereços. Selecionamos novamente o endereço ```legacy```, ao invés de usar o padrão ```bech32```, simplesmente para consistência. Esta é uma situação em que teria sido seguro gerar um endereço Bech32 padrão, apenas usando ```bitcoin-cli getrawchangeaddress```, porque ele seria enviado e recebido por nós em nosso node Bitcoin Core, que tem suporte integral a isso. Mas, estamos adiantando as coisas. Vamos mudar sobre como mudar o endereço para Bech32 na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md). +Observe que isso usa uma nova função: ```getrawchangeaddress```. É basicamente a mesma coisa que o ```getnewaddress```, mas é otimizado para uso como um endereço de troco em uma transação bruta, portanto, não faz coisas como criar entradas em nossa lista de endereços. Selecionamos novamente o endereço ```legacy```, ao invés de usar o padrão ```bech32```, simplesmente para consistência. Esta é uma situação em que teria sido seguro gerar um endereço Bech32 padrão, apenas usando ```bitcoin-cli getrawchangeaddress```, porque ele seria enviado e recebido por nós em nosso node Bitcoin Core, que tem suporte integral a isso. Mas, estamos adiantando as coisas. Mas vamos mudar para Bech32 na seção [§4.6](04_6_Creating_a_Segwit_Transaction.md). Agora temos um endereço adicional em nossa carteira, para que possamos receber o troco de um UTXO! Para usá-lo, precisaremos criar uma transação bruta com duas saídas. -## Escolhendo os UTXOs suficientes +## Escolhendo UTXOs Suficientes -Nosso exemplo de transação bruta era simples também de outra maneira: Assumia que havia dinheiro suficiente em um único UTXO para cobrir toda a transação. Frequentemente, esse será o caso, mas às vezes desejaremos criar transações que gastem mais dinheiro do que temos em um único UTXO. Para fazer isso, devemos criar uma transação bruta com duas (ou mais) entradas. +Nosso exemplo de transação bruta era simples também de outra maneira: assumia que havia dinheiro suficiente em um único UTXO para cobrir toda a transação. Frequentemente, esse será o caso, mas às vezes desejaremos criar transações que gastem mais dinheiro do que temos em um único UTXO. Para fazer isso, devemos criar uma transação bruta com duas (ou mais) entradas. -## Escrevendo uma transação bruta real +## Escrevendo uma Transação Bruta Real -Para resumir: A criação de uma transação bruta real para enviar moedas, às vezes, requer múltiplas entradas e, quase sempre, múltiplas saídas, uma das quais é um endereço de troco. Estaremos criando esse tipo de transação mais realista, um exemplo que mostra um caso de uso da vida real, enviando fundos por meio da segunda metodologia do Bitcoin, as transações brutas. +Para resumir: a criação de uma transação bruta real para enviar moedas, às vezes, requer múltiplas entradas e, quase sempre, múltiplas saídas, uma das quais é um endereço de troco. Estaremos criando esse tipo de transação mais realista, em um exemplo que mostra um caso de uso da vida real, enviando fundos por meio da segunda metodologia do Bitcoin, as transações brutas. -Vamos usar nossos UTXOs 0 e 2: +Vamos usar nossos UTXOs de índice 0 e 2: ``` $ bitcoin-cli listunspent [ @@ -75,7 +75,7 @@ $ bitcoin-cli listunspent ``` Em nosso exemplo, enviaremos 0,009 BTC, que é (um pouco) maior do que qualquer um de nossos UTXOs. Para isso, será necessário que os combinemos e, em seguida, vamos usar nosso endereço de troco para recuperar os fundos não gastos. -### Configurando as variáveis +### Configurando as Variáveis Já temos as variáveis ​​```$changeaddress``` e ```$recipient``` dos exemplos anteriores: ``` @@ -92,15 +92,15 @@ $ utxo_txid_2=$(bitcoin-cli listunspent | jq -r '.[2] | .txid') $ utxo_vout_2=$(bitcoin-cli listunspent | jq -r '.[2] | .vout') ``` -### Escrevendo a transação +### Escrevendo a Transação -Escrever a transação bruta real é surpreendentemente simples. Tudo o que precisamos fazer é incluir um objeto JSON adicional separado por vírgula na matriz JSON de entradas e um par de valores-chave adicional separado por vírgula em um objeto JSON de saídas. +Escrever a transação bruta em si é surpreendentemente simples. Tudo o que precisamos fazer é incluir um objeto JSON adicional separado por vírgula no array JSON de entradas e um par de valores-chave adicional separado por vírgula em um objeto JSON de saída. Aqui temos um exemplo. Observe as múltiplas entradas após o argumento ```inputs``` e as múltiplas saídas após o argumento ```outputs```. ``` $ rawtxhex2=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid_1'", "vout": '$utxo_vout_1' }, { "txid": "'$utxo_txid_2'", "vout": '$utxo_vout_2' } ]''' outputs='''{ "'$recipient'": 0.009, "'$changeaddress'": 0.0009 }''') ``` -Fomos _muito_ cuidadosos em calcular a quantidade. Esses dois UTXOs contêm 0,00999999 BTC. Depois de enviar 0,009 BTC, teremos 0,00099999 BTC restantes. Escolhemos 0,00009999 BTC como a nossa taxa de transação. Para acomodar essa taxa, definimos o troco como sendo 0,0009 BTC. Se não tivermos prestado atenção nisso, e definido nosso troco para 0,00009 BTC, essa quantidade de BTC adicional seria enviado para os mineradores! Se tivéssemos esquecido de fazer o troco, todo o excesso teria desaparecido. Portanto, novamente, _ tenha cuidado_. +Fomos _muito_ cuidadosos em calcular a quantidade. Esses dois UTXOs contêm 0,00999999 BTC. Depois de enviar 0,009 BTC, teremos 0,00099999 BTC restantes. Escolhemos 0,00009999 BTC como a nossa taxa de transação. Para acomodar essa taxa, definimos o troco como sendo 0,0009 BTC. Se não tivéssemos prestado atenção e definido nosso troco como 0,00009 BTC, essa quantidade de BTC adicional seria enviada para os mineradores! Se tivéssemos esquecido de fazer o troco, todo o excesso teria desaparecido. Portanto, novamente, _ tenha cuidado_. Felizmente, podemos verificar três vezes com o alias ```btctxfee``` do Prefácio do JQ: ``` @@ -110,7 +110,7 @@ $ ./txfee-calc.sh $rawtxhex2 ### Concluindo -Agora podemos assinar, selar e entregar nossa transação, e ela é sua (e do faucet): +Agora podemos assinar, selar e entregar nossa transação, e ela será sua (e do faucet): ``` $ signedtx2=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex2 | jq -r '.hex') $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx2 @@ -119,7 +119,7 @@ e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d ### Esperando -Como de costume, nossas moedas estarão no fluxo por um tempo: O troco ficará indisponível até que a transação seja realmente confirmada e um novo UTXO seja nos dado. +Como de costume, nossas moedas estarão no fluxo por um tempo: o troco ficará indisponível até que a transação seja realmente confirmada e um novo UTXO nos seja dado. Mas, em 10 minutos ou menos (provavelmente), teremos o dinheiro restante de volta e totalmente utilizável novamente. Por enquanto, ainda precisamos esperar: ``` @@ -170,18 +170,18 @@ E o troco eventualmente voltará para nós: } ] ``` -Este também pode ser um bom momento para revisitar um explorador de blockchain, para que possamos ver mais intuitivamente como as entradas, saídas e as taxas estão dispostas na transação: [e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://mempool.space/pt/testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d). +Este também pode ser um bom momento para revisitar um explorador de blockchain, para que possamos ver mais intuitivamente como as entradas, saídas e taxas estão dispostas na transação: [e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d](https://mempool.space/pt/testnet/tx/e7071092dee0b2ae584bf6c1ee3c22164304e3a17feea7a32c22db5603cd6a0d). -## Resumo do Enviando bitcoins usando transações brutas +## Resumo: Enviando Moedas com Transações Brutas Para enviar moedas usando transações brutas, precisamos criar uma transação bruta com uma ou mais entradas (para ter fundos suficientes) e uma ou mais saídas (para recuperar usando o troco). Então, podemos seguir nosso procedimento normal de usar o ```createrawtransaction``` com argumentos nomeados junto com o JQ, conforme descrito nas seções anteriores. -> :fire: ***Qual é o ponto positivo de enviar moedas com transações brutas?*** +> :fire: ***Qual é o poder de enviar moedas com transações brutas?*** > _As vantagens._ Oferece maior controle. Se o nosso objetivo é escrever um programa ou script Bitcoin mais complexo, provavelmente usaremos as transações brutas para saber exatamente o que está acontecendo. Essa também é a situação mais _segura_ para usar transações brutas, porque podemos garantir que não cometeremos nenhum erro na parte da programação. > _As desvantagens._ É muito fácil perder dinheiro. Não há avisos, bloqueios e barreiras na programação, a não ser que as criemos. Também é tudo muito misterioso. A formatação é desagradável, mesmo usando a interface ```bitcoin-cli``` que é fácil de usar, e temos que fazer muitas pesquisas e cálculos manualmente. -## O que vem depois? +## O Que Vem Depois? -Veja uma forma alternativa de inserir comandos no [Prefácio: Usando o JQ] (04_4__Interlude_Using_Curl.md). +Veja uma forma alternativa de inserir comandos no [Prefácio: Usando JQ](04_4__Interlude_Using_Curl.md). -Ou, se preferir pular, o que é francamente uma digressão, podemos aprender mais com "Enviando Transações de Bitcoin" na sessão [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file +Ou, se preferir pular o que é francamente uma digressão, podemos aprender mais uma forma de enviar transações no Bitcoin na seção [§4.5 Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file From 2dcf2b9d60d30262226f829ab2c2aab5485be2f2 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 1 Jul 2021 16:50:03 -0300 Subject: [PATCH 43/50] Review 04_4_Interlude --- pt/04_4__Interlude_Using_Curl.md | 76 ++++++++++++++++---------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/pt/04_4__Interlude_Using_Curl.md b/pt/04_4__Interlude_Using_Curl.md index a6957ac..f987b4a 100644 --- a/pt/04_4__Interlude_Using_Curl.md +++ b/pt/04_4__Interlude_Using_Curl.md @@ -1,17 +1,16 @@ -# Prefácio: Acessando o Bitcoind com Curl +# Prefácio: Usando Curl -O ```bitcoin-cli``` é, em última análise, apenas um invólucro. É uma forma de interagir com ```bitcoind``` a partir da linha de comando, fornecendo acesso simplificado aos seus diversos comandos RPC. Mas o RPC pode, é claro, ser acessado diretamente. É disso que iremos falar nessa sessão: Como nos conectarmos diretamente ao RPC com o comando ```curl```. +O ```bitcoin-cli``` é, em última análise, apenas um invólucro. É uma forma de interagir com ```bitcoind``` a partir da linha de comando, fornecendo acesso simplificado aos seus diversos comandos RPC. Mas o RPC pode, é claro, ser acessado diretamente. É disso que iremos falar nessa seção: como nos conectarmos diretamente ao RPC com o comando ```curl```. -It won't be used much in the future chapters, but it's an important building block that you can see as an alternative access to `bitcoind` is you so prefer. Não será muito usado nos próximos capítulos, mas essas informações serão importantes caso queiramos uma alternativa para acessar o ```bitcoind```. ## Conhecendo o Curl -O ```curl```, abreviação de "ver URL", é uma ferramenta de linha de comando que permite acessar URLs diretamente usando a linha de comando. É uma maneira fácil de interagir com servidores como o ```bitcoind```, que ficam ouvindo as portas da internet e conversam utilizando uma variedade de protocolos. O Curl também está disponível como uma biblioteca para muitas linguagens de programação, como C, Java, PHP e Python. Então, depois de saber como trabalhar com o Curl, teremos uma base sólida para usar várias APIs diferentes. +O ```curl```, abreviação de "ver URL" ("see URL" em inglês), é uma ferramenta que nos permite acessar URLs diretamente pela linha de comando. É uma maneira fácil de interagir com servidores como o ```bitcoind```, que ficam ouvindo as portas da internet e conversam utilizando uma variedade de protocolos. O Curl também está disponível como uma biblioteca para muitas linguagens de programação, como C, Java, PHP e Python. Então, depois de saber como trabalhar com o Curl, teremos uma base sólida para usar várias APIs diferentes. -Para usar o ```curl``` com o ```bitcoind```, devemos saber três coisas: O formato padrão, o nome de usuário e senha e a porta correta. +Para usar o ```curl``` com o ```bitcoind```, devemos saber três coisas: o formato padrão, o nome de usuário e senha e a porta correta. -### Conhecendo o formato +### Conhecendo o Formato Os comandos ```bitcoin-cli``` estão todos vinculados aos comandos RPC no ```bitcoind```. Isso torna a transição do uso de ```bitcoin-cli``` para o uso do ```curl``` muito simples. Na verdade, se olharmos qualquer uma das páginas de ajuda do ```bitcoin-cli```, veremos que eles listam não apenas os comandos ```bitcoin-cli```, mas também os comandos ```curl``` paralelos. Por exemplo, aqui temos o resultado do comando ```bitcoin-cli help getmininginfo```: ``` @@ -35,13 +34,13 @@ Examples: > bitcoin-cli getmininginfo > curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getmininginfo", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ ``` -E tem o comando ```curl```, no final da tela de ajuda! Este comando um tanto longo tem quatro partes principais: (1) Uma lista do nome de usuário; (2) Um sinalizador ```--data-binary```; (3) Um objeto JSON que diz ao ```bitcoind``` o que fazer, incluindo um array JSON com os parâmetros e; (4) Um cabeçalho HTTP que inclui a URL do ```bitcoind```. +E ali está o comando ```curl```, no final da tela de ajuda! Este comando um tanto longo tem quatro partes principais: (1) uma lista do nome de usuário; (2) um sinalizador ```--data-binary```; (3) um objeto JSON que diz ao ```bitcoind``` o que fazer, incluindo um array JSON com os parâmetros e; (4) um cabeçalho HTTP que inclui a URL do ```bitcoind```. Quando estamos trabalhando com o ```curl```, muitos desses argumentos do ```curl``` permanecerão os mesmos de um comando para outro, apenas as entradas ```method``` e ```params``` no array JSON normalmente mudam. No entanto, precisaremos saber como preencher o nome do usuário e endereço da URL para que funcione, antes de mais nada! _Sempre que não tivermos certeza sobre como usar o curl no RPC, basta usarmos a ajuda do bitcoin-cli e continuar._ -### Descobrindo o nome de usuário +### Descobrindo o Nome de Usuário Para falar com a porta do ```bitcoind```, precisamos de um nome de usuário e senha. Eles foram criados como parte da configuração inicial do Bitcoin e podem ser encontrados no arquivo `~/.bitcoin/bitcoin.conf`. @@ -73,7 +72,7 @@ rpcport=18443 ``` Nosso nome de usuário é ```StandUp``` e nossa senha é ```8eaf562eaf45c33c3328bc66008f2dd1```. -> **Atenção:** Obviamente, não é muito seguro ter essas informações em um arquivo de texto simples. A partir do Bitcoin Core 0.12, podemos omitir o ```rpcpassword``` do arquivo ```bitcoin.conf``` e fazer com que o ```bitcoind``` gere um novo cookie sempre que iniciarmos o serviço. A desvantagem disso é que torna o uso de comandos RPC por outros aplicativos, como os detalhados neste capítulo, mais difícil. Então, vamos ficar com as informações simples do ```rpcuser``` e ```rpcpassword``` por enquanto, mas para softwares em produção, é importante considerarmos essa alteração para cookies. +> **ATENÇÃO:** Obviamente, não é muito seguro ter essas informações em um arquivo de texto simples. A partir do Bitcoin Core 0.12, podemos omitir o ```rpcpassword``` do arquivo ```bitcoin.conf``` e fazer com que o ```bitcoind``` gere um novo cookie sempre que iniciarmos o serviço. A desvantagem disso é que torna o uso de comandos RPC por outros aplicativos, como os detalhados neste capítulo, mais difícil. Então, vamos ficar com as informações simples do ```rpcuser``` e ```rpcpassword``` por enquanto, mas para softwares em produção, é importante considerarmos essa alteração para cookies. A maneira segura de usar o RPC com ```bitcoind``` é a seguinte: ``` @@ -88,17 +87,17 @@ A maneira insegura e errada de fazer isso é a seguinte: ``` $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ ``` -> **Atenção:** Digitar a senha na linha de comando pode colocá-la na tabela de processos e/ou salvá-la em um histórico qualquer. Isso é ainda menos recomendado do que colocá-la em um arquivo, exceto para testes utilizando a testnet. Se quisermos fazer em qualquer outro lugar, precisamos nos certificar de saber o que estamos fazendo! +> **ATENÇÃO:** Digitar a senha na linha de comando pode colocá-la na tabela de processos e/ou salvá-la em um histórico qualquer. Isso é ainda menos recomendado do que colocá-la em um arquivo, exceto para testes utilizando a testnet. Se quisermos fazer em qualquer outro lugar, precisamos nos certificar de saber o que estamos fazendo! -### Conhecendo os comandos e os parâmetros +### Conhecendo os Comandos e os Parâmetros Com tudo isso em mãos, estamos prontos para enviar os comandos RPC padrão com o ```curl```, mas ainda precisamos saber como incorporar os dois elementos que tendem a mudar no comando ```curl```. O primeiro é o ```method```, que é o método RPC que está sendo utilizado. Isso geralmente deve corresponder aos nomes de comando que alimentamos no ```bitcoin-cli``` por muito tempo. -O segundo é o ```params```, que é uma matriz JSON de parâmetros. Eles são iguais aos argumentos (ou argumentos nomeados) que estamos usando. Eles também são a parte mais confusa do ```curl```, em grande parte porque são um array estruturado ao invés de uma simples lista. +O segundo é o ```params```, que é uma array JSON de parâmetros. Eles são iguais aos argumentos (ou argumentos nomeados) que estamos usando. Eles também são a parte mais confusa do ```curl```, em grande parte porque são um array estruturado ao invés de uma simples lista. -Esta é a aparência de algumas matrizes de parâmetros: +Esta é a aparência de alguns arrays de parâmetros: * `[]` — Um array vazio; * `["000b4430a7a2ba60891b01b718747eaf9665cb93fbc0c619c99419b5b5cf3ad2"]` — Um array com dados; @@ -107,7 +106,7 @@ Esta é a aparência de algumas matrizes de parâmetros: * `{}` - Um objeto vazio; * `[''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.298, "'$changeaddress'": 1.0}'']` — Um array com um array contendo um objeto e um objeto vazio. -## Obtendo a informação +## Obtendo Informação Agora podemos enviar nosso primeiro comando ```curl``` acessando o RPC ```getmininginfo```: ``` @@ -115,10 +114,9 @@ $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc" {"result":{"blocks":1772428,"difficulty":10178811.40698772,"networkhashps":91963587385939.06,"pooledtx":61,"chain":"test","warnings":"Warning: unknown new rules activated (versionbit 28)"},"error":null,"id":"curltest"}``` Note that we provided the method, `getmininginfo`, and the parameter, `[]`, but that everything else was the standard `curl` command line. ``` -> **Atenção:** Se obtivermos como resultado o seguinte erro: "Failed to connect to 127.0.0.1 port 8332: Connection refused", precisamos nos certificar de que uma linha como ```rpcallowip = 127.0.0.1``` esteja configurada no ```~/.bitcoin/bitcoin.conf```. Se ainda não funcionar, precisaremos permitir o acesso à porta 18332 (ou 8332) do nosso host local. Nossa configuração padrão do [Capítulo 2: Configurando um Bitcoin-Core no VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) deve fazer tudo isso. +> **ATENÇÃO:** Se obtivermos como resultado o seguinte erro: "Failed to connect to 127.0.0.1 port 8332: Connection refused", precisamos nos certificar de que uma linha como ```rpcallowip = 127.0.0.1``` esteja configurada no ```~/.bitcoin/bitcoin.conf```. Se ainda não funcionar, precisaremos permitir o acesso à porta 18332 (ou 8332) do nosso host local. Nossa configuração padrão do [Capítulo 2: Configurando um Bitcoin-Core VPS](02_0_Setting_Up_a_Bitcoin-Core_VPS.md) deve fazer tudo isso. -The result is another JSON array, which is unfortunately ugly to read if you're using `curl` by hand. Fortunately, you can clean it up simply by piping it through `jq`: -O resultado é outro array JSON, que infelizmente é ruim de se ler se estivermos usando o ```curl``` manualmente. Felizmente, podemos limpá-lo simplesmente usando o ```jq```: +O resultado é outro array JSON, que infelizmente é ruim de ler se estivermos usando o ```curl``` manualmente. Felizmente, podemos limpá-lo simplesmente usando o ```jq```: ``` $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getmininginfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' % Total % Received % Xferd Average Speed Time Time Time Current @@ -137,13 +135,13 @@ $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc" "id": "curltest" } ``` -Você verá um pouco de relatório de conectividade à medida que os dados são baixados, então, quando os dados chegarem a ```jq```, tudo será corretamente identado. Estaremos omitindo as informações do download nos próximos exemplos. +Você verá um pouco de relatório de conectividade à medida que os dados são baixados, então, quando os dados chegarem ao ```jq```, tudo será corretamente identado. Estaremos omitindo as informações do download nos próximos exemplos. -## Manipulando nossa carteira +## Manipulando Nossa Carteira Embora já estejamos acessando o ```bitcoind``` diretamente, ainda teremos acesso à funcionalidade de carteira, porque ela está amplamente armazenada no próprio ```bitcoind```. -### Pesquisando endereços +### Pesquisando Endereços Usando o RPC ```getaddressesbylabel``` para listar todos os nossos endereços atuais: ``` @@ -177,7 +175,7 @@ Este é o nosso primeiro exemplo de um parâmetro real, ```" "```. Este é o par O resultado é uma lista de todos os endereços que foram usados na nossa carteira. Alguns dos quais presumivelmente possuem saldo. -### Pesquisando pelos saldos +### Pesquisando Saldos Use o RPC ```listunspent``` para listar os saldos que temos disponíveis: ``` @@ -214,11 +212,11 @@ $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc" "id": "curltest" } ``` -Esta é quase exatamente a mesma saída que recebemos quando digitamos ```bitcoin-cli listunspent```, mostrando como as duas interfaces estão intimamente ligadas. Se nenhuma limpeza ou ajuda extra for necessária, então o ```bitcoin-cli``` apenas produzirá o RPC. Simples assim! +Esta é quase a mesma saída que recebemos quando digitamos ```bitcoin-cli listunspent```, mostrando como as duas interfaces estão intimamente ligadas. Se nenhuma limpeza ou ajuda extra for necessária, então o ```bitcoin-cli``` apenas produzirá o RPC. Simples assim! -### Criando um endereço +### Criando um Endereço -Depois de saber onde estão os saldos, a próxima etapa na elaboração de uma transação é obter um endereço de alteração. Agora provavelmente já pegamos o jeito e sabemos que para os comandos RPC simples, tudo que precisamos fazer é ajustar o ```method``` no comando ```curl```: +Depois de saber onde os saldos estão, a próxima etapa na elaboração de uma transação é obter um endereço de troco. Agora provavelmente já pegamos o jeito e sabemos que para os comandos RPC simples, tudo que precisamos fazer é ajustar o ```method``` no comando ```curl```: ``` $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getrawchangeaddress", "params": ["legacy"] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.' { @@ -236,15 +234,15 @@ mqdfnjgWr2r3sCCeuTDfe8fJ1CnycF2e6R ``` Não precisamos nos preocupar com as informações do download. Ele irá para o ```STDERR``` e será exibido em nossa tela, enquanto os resultados irão para o ```STDOUT``` e serão salvos em nossa variável. -## Criando uma transação +## Criando uma Transação Agora estamos prontos para criar uma transação com o ```curl```. -### Preparando as variáveis +### Preparando as Variáveis -Assim como no ```bitcoin-cli```, para criar uma transação usando o Curl com o RPC, devemos primeiro salvar nossas variáveis. A única mudança aqui é que o ```curl``` cria um objeto JSON que inclui um valor-chave ```result```, então sempre precisaremos usar o pipe (```|```) através da tag ```.result``` antes de fazer qualquer outra coisa. +Assim como no ```bitcoin-cli```, para criar uma transação usando o Curl com o RPC, devemos primeiro salvar nossas variáveis. A única mudança aqui é que o ```curl``` cria um objeto JSON que inclui um valor-chave ```result```, então sempre precisaremos usar o pipe (```|```) através da tag ```.result``` antes de fazer outra coisa qualquer. -Este exemplo configura nossas variáveis para usar o BTC de 1.2985 em fundos listados na primeira transação não gasta acima: +Este exemplo configura nossas variáveis para usar o BTC de 1.2985 em fundos listados na primeira transação não-gasta acima: ``` $ utxo_txid=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .txid') $ utxo_vout=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "listunspent", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result | .[0] | .vout') @@ -261,7 +259,7 @@ $ echo $changeaddress n2jf3MzeFpFGa7wq8rXKVnVuv5FoNSJZ1N ``` -### Criando a transação +### Criando a Transação A transação criada com o ```curl``` é muito semelhante à transação criada com o ```bitcoin-cli```, mas com algumas diferenças sutis: ``` @@ -276,18 +274,18 @@ O coração da transação é, obviamente, o array JSON ```params```, que estamo Podemos observar que todos os ```params``` estão alojados nos ```[]``` para marcar o array de parâmetros. -Nós também variamos as citações de como as coisas funcionavam no ```bitcoin-cli```, para iniciar e terminar cada array e objeto dentro do array ```params``` com ```''``` ao invés do tradicional ```'' '```. Isso porque todo o conjunto de argumentos JSON já tem um ```'``` em torno dele. Como de costume, basta dar uma olhada na bizarra citação do shell e se acostumar com isso. +Nós também variamos as citações de como as coisas funcionavam no ```bitcoin-cli```, para iniciar e terminar cada array e objeto dentro do array ```params``` com ```''``` ao invés do tradicional ```'''```. Isso porque todo o conjunto de argumentos JSON já tem um ```'``` em torno dele. Como de costume, basta dar uma olhada na bizarra citação do shell e se acostumar com isso. -No entanto, há uma última coisa a ser observada neste exemplo, e pode ser _enlouquecedor_ se não tivermos percebido. Quando executamos um comando ```createrawtransaction``` com ```bitcoin-cli```, o array JSON de entradas e o objeto JSON de saídas eram parâmetros distintos, portanto, foram separados por um espaço. Agora, porque eles são parte do array JSON ```params```, eles são separados por uma vírgula (```,```). Se não tivermos percebido isso obteremos um ```parse error``` sem muitas informações. +No entanto, há uma última coisa a ser observada neste exemplo, e pode ser _enlouquecedor_ se não tivermos percebido. Quando executamos um comando ```createrawtransaction``` com ```bitcoin-cli```, o array JSON de entradas e o objeto JSON de saídas eram parâmetros distintos, portanto, foram separados por um espaço. Agora, porque eles são parte do array JSON ```params```, eles são separados por uma vírgula (```,```). Se não tivéssemos percebido isso obteríamos um ```parse error``` sem muitas informações. -> **Atenção:** Todo mundo já teve problemas para depurar o ```curl```, não é mesmo? Para resolver isso basta adicionar o argumento ```--trace-ascii/tmp/foo```. Informações completas sobre o que está sendo enviado ao servidor serão salvas em ```/tmp/foo``` (ou qualquer nome de arquivo que quisermos informar). +> **ATENÇÃO:** Todo mundo já teve problemas para depurar o ```curl```, não é mesmo? Para resolver isso basta adicionar o argumento ```--trace-ascii/tmp/foo```. Informações completas sobre o que está sendo enviado ao servidor serão salvas em ```/tmp/foo``` (ou qualquer nome de arquivo que quisermos informar). -Depois de verificarmos se as coisas estão funcionando, provavelmente iremos desejar salvar o código hexadecimal em uma variável: +Depois de verificarmos se as coisas estão funcionando, provavelmente desejaremos salvar o código hexadecimal em uma variável: ``` $ hexcode=$(curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createrawtransaction", "params": [''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]'', ''{ "'$recipient'": 0.0003, "'$changeaddress'": 0.0005}'']}' -H 'content-type: text/plain;' http://127.0.0.1:18332/ | jq -r '.result') ``` -### Assinando e enviando +### Assinando e Enviando Assinar e enviar a nossa transação usando ```curl``` é bem simples, basta usar os seguintes comandos do RPC ```signrawtransactionwithwallet``` e ```sendrawtransaction```: @@ -301,14 +299,14 @@ $ curl --user StandUp:8eaf562eaf45c33c3328bc66008f2dd1 --data-binary '{"jsonrpc" "id": "curltest" } ``` -## Resumo do Acessando o Bitcoind com Curl +## Resumo: Acessando o Bitcoind com Curl -Terminando esta seção, podemos sentir que acessar o ```bitcoind``` através de ```curl``` é muito parecido com acessá-lo através de ```bitcoin-cli```, porém, é mais complicado. E estamos certos. O ```bitcoin-cli``` tem funcionalidade RPC bem completa, então qualquer coisa que fizermos através do ```curl``` provavelmente poderemos fazer através do ```bitcoin-cli```. É por isso que vamos continuar nos concentrando no ```bitcoin-cli``` após esta digressão. +Terminando esta seção, podemos sentir que acessar o ```bitcoind``` através de ```curl``` é muito parecido com acessá-lo através de ```bitcoin-cli```, porém, é mais complicado. E estamos certos. O ```bitcoin-cli``` tem funcionalidade RPC bem completa, então qualquer coisa que fizermos através do ```curl``` provavelmente poderemos fazer através do ```bitcoin-cli```. E é por isso que vamos continuar nos concentrando no ```bitcoin-cli``` após esta digressão. Mas ainda há razões para usar ```curl``` ao invés do ```bitcoin-cli```: -_Qual é o poder do curl?_ Obviamente, o ```curl``` elimina um nível intermediário. Ao invés de trabalhar com o ```bitcoin-cli```, que envia comandos RPC para o ```bitcoind```, estamos enviando esses comandos RPC diretamente para ele. Isso permite uma programação mais robusta, porque não precisamos nos preocupar com as coisas inesperadas que o ```bitcoin-cli``` pode fazer ou como isso pode mudar com o tempo. No entanto, também estamos dando os primeiros passos para usar uma linguagem de programação mais abrangente do que as opções pobres oferecidas por um script de shell. Como veremos nos últimos capítulos deste livro, podemos realmente ver que as bibliotecas curl são outras funções que acessam os comandos RPC em uma variedade de linguagens de programação: Mas isso ainda está muito longe, ainda. +_Qual é o poder do curl?_ Obviamente, o ```curl``` elimina um nível intermediário. Ao invés de trabalhar com o ```bitcoin-cli```, que envia comandos RPC para o ```bitcoind```, estamos enviando esses comandos RPC diretamente para ele. Isso permite uma programação mais robusta, porque não precisamos nos preocupar com as coisas inesperadas que o ```bitcoin-cli``` pode fazer ou como isso pode mudar com o tempo. No entanto, também estamos dando os primeiros passos para usar uma linguagem de programação mais abrangente do que as opções pobres oferecidas por um script de shell. Como veremos nos últimos capítulos deste livro, podemos realmente ver que as bibliotecas curl são outras funções que acessam os comandos RPC em uma variedade de linguagens de programação: mas isso ainda está muito longe. -## O que vem depois? +## O Que Vem Depois? -Aprenda mais uma maneira de "Enviando Transações de Bitcoin" com [§4.5 Enviando bitcoins usando transações brutas automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file +Aprenda mais uma maneira de enviar transações no Bitcoin com [§4.5 Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md). \ No newline at end of file From 676f753b68002219f43d1875876e4d387d2ed78f Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 1 Jul 2021 17:00:12 -0300 Subject: [PATCH 44/50] Review 04_5 --- ...g_Coins_with_Automated_Raw_Transactions.md | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md b/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md index 91926ae..6308054 100644 --- a/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md +++ b/pt/04_5_Sending_Coins_with_Automated_Raw_Transactions.md @@ -1,25 +1,25 @@ -# 4.5: Enviando bitcoins usando transações brutas automatizadas +# 4.5: Enviando Moedas com Transações Brutas Automatizadas -Este capítulo apresenta três maneiras de enviar fundos por meio da interface cli do Bitcoin. A sessão [§4.1](04_1_Sending_Coins_The_Easy_Way.md) descreveu como fazer isso com um comando simples, a sessão [§4.4](04_4_Sending_Coins_with_a_Raw_Transaction.md) detalhou como usar uma transação bruta mais perigosa. Esta seção fica no meio termo de ambas, mostrando como tornar as transações brutas mais simples e seguras. +Este capítulo apresenta três maneiras de enviar fundos por meio da interface cli do Bitcoin. A seção [§4.1](04_1_Sending_Coins_The_Easy_Way.md) descreveu como fazer isso com um comando simples e a seção [§4.4](04_4_Sending_Coins_with_a_Raw_Transaction.md) detalhou como usar uma transação bruta mais perigosa. Esta seção fica no meio termo de ambas, mostrando como tornar as transações brutas mais simples e seguras. -## Deixando o Bitcoin fazer os cálculos para nós +## Deixando o Bitcoin Fazer os Cálculos Para Nós -A metodologia para transações brutas automatizadas é simples: Criamos uma transação bruta, mas usamos o comando ```fundrawtransaction``` para pedir ao bitcoind para executar os cálculos para nós. +A metodologia para transações brutas automatizadas é simples: criamos uma transação bruta, mas usamos o comando ```fundrawtransaction``` para pedir ao bitcoind para executar os cálculos para nós. -Para usar este comando, precisaremos garantir que nosso arquivo ```~/.bitcoin/bitcoin.conf``` contenha as variáveis racionais para calcular as taxas de transação. Podemos consultar a sessão [§4.1: Enviando bitcoins no modo easy](04_1_Sending_Coins_The_Easy_Way.md) para obter mais informações sobre isso. +Para usar este comando, precisaremos garantir que nosso arquivo ```~/.bitcoin/bitcoin.conf``` contenha as variáveis racionais para calcular as taxas de transação. Podemos consultar a seção [§4.1: Enviando Moedas da Maneira Fácil](04_1_Sending_Coins_The_Easy_Way.md) para obter mais informações sobre isso. Vamos usar números conservadores, por isso sugerimos adicionar o seguinte ao `bitcoin.conf`: ``` mintxfee=0.0001 txconfirmtarget=6 ``` -Para manter o tutorial em constante movimento (em outras palavras, para movimentarmos nosso dinheiro rápido sem ficar esperando muito), sugerimos o seguinte: +Para manter o tutorial em movimento (e para movimentarmos nosso dinheiro rapidamente), sugerimos o seguinte: ``` mintxfee=0.001 txconfirmtarget=1 ``` -## Criando uma transação bruta +## Criando uma Transação Bruta Para usar o ```fundrawtransaction``` primeiro precisamos criar uma transação bruta básica que liste _nenhuma_ entrada e _nenhuma_ mudança de endereço. Apenas listaremos o nosso destinatário e quanto desejamos enviar, neste caso ```$recipient``` e ```0,0002``` BTC. ``` @@ -27,7 +27,7 @@ $ recipient=n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi $ unfinishedtx=$(bitcoin-cli -named createrawtransaction inputs='''[]''' outputs='''{ "'$recipient'": 0.0002 }''') ``` -## Financiando nossa transação bruta +## Financiando Nossa Transação Bruta Dizemos ao ```bitcoin-cli``` para financiar essa transação básica: ``` @@ -42,11 +42,11 @@ Isso fornece muitas informações úteis, mas uma vez que tenhamos certeza de co ``` $ rawtxhex3=$(bitcoin-cli -named fundrawtransaction hexstring=$unfinishedtx | jq -r '.hex') ``` -## Verificando nossa transação financiada +## Verificando Nossa Transação Financiada Parece mágica, então nas primeiras vezes que usarmos o ```fundrawtransaction```, provavelmente vamos querer verificá-la. -Vamos executar o comando ```decoderawtransaction``` para mostrar que a transação bruta agora está disposta corretamente, usando um ou mais dos nossos UTXOs e enviando fundos excedentes de volta para um endereço de alteração: +Vamos executar o comando ```decoderawtransaction``` para mostrar que a transação bruta agora está disposta corretamente, usando um ou mais dos nossos UTXOs e enviando fundos excedentes de volta para um endereço de troco: ``` $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 { @@ -98,14 +98,14 @@ $ bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex3 ] } ``` -Uma coisa de interesse aqui é o endereço de troco, que é o segundo ```vout```. Observe que é um endereço ```tb1```, o que significa que é do tipo Bech32. Quando demos ao Bitcoin Core a capacidade total de gerenciar as alterações, ele o fez usando o tipo de endereço padrão, Bech32, e funcionou bem. É por isso que nossa mudança para endereços SegWit na sessão [§4.6](04_6_Creating_a_Segwit_Transaction.md) realmente não é um grande negócio, mas existem algumas dicas para uso mais amplo, sobre as quais falaremos lá. +Uma coisa de interesse aqui é o endereço de troco, que é o segundo ```vout```. Observe que é um endereço ```tb1```, o que significa que é do tipo Bech32. Quando demos ao Bitcoin Core a capacidade total de gerenciar as alterações, ele o fez usando o tipo de endereço padrão, Bech32, e funcionou bem. É por isso que nossa mudança para endereços SegWit na seção [§4.6](04_6_Creating_a_Segwit_Transaction.md) realmente não é um grande negócio, mas existem algumas dicas para uso mais amplo, sobre as quais falaremos lá. -Embora tenhamos visto a taxa na saída no ```fundrawtransaction```, ela não pode ser visível aqui. No entanto, podemos verificar isso com o script JQ ```txfee-calc.sh``` criado na sessão [Prefácio: Usando o JQ](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master /04_2__Interlude_Using_JQ.md): +Embora tenhamos visto a taxa na saída de ```fundrawtransaction```, ela não pode ser visível aqui. No entanto, podemos verificar isso com o script JQ ```txfee-calc.sh``` criado na seção [Prefácio: Usando JQ](https://github.com/BlockchainCommons/Learning-Bitcoin-from-the-Command-Line/blob/master/04_2__Interlude_Using_JQ.md): ``` $ ~/txfee-calc.sh $rawtxhex3 .000222 ``` -Finalmente, podemos usar o ```getaddressinfo``` para ver se o endereço de alteração gerado realmente nos pertence: +Finalmente, podemos usar o ```getaddressinfo``` para ver se o endereço de troco gerado realmente nos pertence: ``` $ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2zzr592r { @@ -129,9 +129,9 @@ $ bitcoin-cli -named getaddressinfo address=tb1q57p0f3hpuad9kf8n6e6adugmt6lnkg2z ] } ``` -Observe os conteúdo do `ismine`. +Observe o conteúdo do `ismine`. -## Enviando a transação financiada +## Enviando a Transação Financiada Neste ponto, podemos assinar e enviar a transação normalmente. ``` @@ -158,14 +158,14 @@ $ bitcoin-cli listunspent ] ``` -## Resumo do Enviando bitcoins usando transações brutas automatizadas +## Resumo: Enviando Moedas com Transações Brutas Automatizadas Se formos enviar fundos usando transações brutas, então o ```fundrawtransaction``` oferece uma boa alternativa onde taxas, entradas e saídas são calculadas para nós, para que não percamos acidentalmente muito dinheiro. > :fire: ***Qual é o poder de enviar moedas com transações brutas automatizadas?*** -> _As vantagens._ Proporciona um bom meio de campo. Se estamos enviando fundos manualmente e o ```sendtoaddress``` não oferece controle suficiente por qualquer motivo, podemos obter algumas das vantagens das transações brutas sem os perigos dela. Essa metodologia deve ser usada sempre que possível se estivermos enviando transações brutas manualmente. -> _As desvantagens._ É uma meio termo. Embora existam algumas opções adicionais no ```fundrawtransaction``` que não foram mencionadas aqui, nosso controle ainda é limitado. Provavelmente, nunca desejaríamos usar esse método se formos escrever um programa cujo objetivo é saber exatamente o que está acontecendo. +> _As vantagens._ Proporciona um bom meio termo. Se estamos enviando fundos manualmente e o ```sendtoaddress``` não oferece controle suficiente por qualquer motivo, podemos obter algumas das vantagens das transações brutas sem os perigos dela. Essa metodologia deve ser usada sempre que possível se estivermos enviando transações brutas manualmente. +> _As desvantagens._ É uma mistura. Embora existam algumas opções adicionais no ```fundrawtransaction``` que não foram mencionadas aqui, nosso controle ainda é limitado. Provavelmente, nunca desejaríamos usar esse método se formos escrever um programa cujo objetivo é saber exatamente o que está acontecendo. -## O que vem depois? +## O Que Vem Depois? -Vamos concluir o capítulo "Enviando transações no Bitcoin" com a sessão [§4.6: Criando uma transação do tipo SegWit](04_6_Creating_a_Segwit_Transaction.md). \ No newline at end of file +Vamos concluir o capítulo "Enviando Transações no Bitcoin" com a seção [§4.6: Criando uma Transação SegWit](04_6_Creating_a_Segwit_Transaction.md). \ No newline at end of file From 30112af2ea20d9dba4bdccf64aca4ecf51e2c9f3 Mon Sep 17 00:00:00 2001 From: namcios Date: Thu, 1 Jul 2021 17:20:22 -0300 Subject: [PATCH 45/50] Review 04_6 --- pt/04_6_Creating_a_Segwit_Transaction.md | 56 ++++++++++++------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/pt/04_6_Creating_a_Segwit_Transaction.md b/pt/04_6_Creating_a_Segwit_Transaction.md index 1064409..f037984 100644 --- a/pt/04_6_Creating_a_Segwit_Transaction.md +++ b/pt/04_6_Creating_a_Segwit_Transaction.md @@ -1,22 +1,22 @@ -# 4.6: Criando uma transação do tipo SegWit +# 4.6: Criando uma Transação SegWit > :information_source: **NOTA:** Esta seção foi adicionada recentemente ao curso e é um esboço que ainda pode estar aguardando revisão. Portanto, leitor, tenha cuidado. -Era uma vez, nos céus do Bitcoin, uma guerra entre os tamanhos de blocos eclodiu. As taxas disparavam e os usuários estavam preocupados se o Bitcoin podia realmente escalar. Os desenvolvedores do Bitcoin Core relutaram em simplesmente aumentar o tamanho do bloco, mas chegaram a um acordo: Fizeram o SegWit, que significa Segregated Witness. A Segregated Witness é uma maneira elegante de dizer "Assinatura Separada". Ele cria novos tipos de transações que removem assinaturas no final da transação. Ao combinar isso com o aumento dos tamanhos de bloco que são visíveis apenas para nós atualizados, o SegWit resolveu os problemas de dimensionamento do Bitcoin na época e também resolveu um bug de maleabilidade desagradável, tornando o dimensionamento ainda melhor para protocolos de segunda camada, como a Lightning Network. +Era uma vez, nos céus do Bitcoin, uma guerra entre os tamanhos de blocos. As taxas disparavam e os usuários estavam preocupados se o Bitcoin podia realmente escalar. Os desenvolvedores do Bitcoin Core relutaram em simplesmente aumentar o tamanho do bloco, mas chegaram a um acordo: fizeram o SegWit, que significa Segregated Witness. Segregated Witness é uma maneira elegante de dizer "Assinatura Separada". Ele cria novos tipos de transações que removem assinaturas no final da transação. Ao combinar isso com o aumento dos tamanhos de bloco que são visíveis apenas para nodes atualizados, o SegWit resolveu os problemas de dimensionamento do Bitcoin na época e também resolveu um bug de maleabilidade desagradável, tornando o dimensionamento ainda melhor para protocolos de segunda camada, como a Lightning Network. -A sacada? O SegWit usa endereços diferentes, alguns dos quais são compatíveis com nodes mais antigos e outros não. +A sacada? O SegWit usa endereços diferentes, alguns dos quais são compatíveis com nodes mais antigos, ao passo que outros não. > :warning: **AVISO DE VERSÃO:** O SegWit foi introduzido no BitCoin 0.16.0, que foi descrito na época como tendo "suporte total". Dito isso, havia algumas falhas na integração com o ```bitcoin-cli``` na época, que impediam a assinatura de funcionar corretamente em novos endereços P2SH-SegWit. O endereço Bech32, não compatível com versões anteriores, também foi introduzido no Bitcoin 0.16.0 e se tornou o tipo de endereço padrão no Bitcoin 0.19.0. Toda essa funcionalidade deve estar totalmente funcional em relação às funções ```bitcoin-cli``` (e, portanto, devem funcionar completamente neste tutorial). -> O problema está em interagir com o mundo. Todos devem ser capazes de enviar para um endereço P2SH-SegWit porque foi construído propositadamente para suportar compatibilidade com as versões anteriores, envolvendo a funcionalidade SegWit em um Script Bitcoin. O mesmo não é verdade para endereços Bech32: Se alguém nos disser que não pode enviar para o nosso endereço Bech32 precisaremos gerar um endereço ```legado``` ou P2SH-SegWit para fazer a transação. (Muitos sites, principalmente as exchanges, também não podem gerar ou receber em endereços SegWit, particularmente endereços Bech32, mas isso é um problema totalmente diferente e não afeta o uso delas). +> O problema está em interagir com o mundo. Todos devem ser capazes de enviar para um endereço P2SH-SegWit porque foi construído propositadamente para suportar compatibilidade com as versões anteriores, envolvendo a funcionalidade SegWit em um Script Bitcoin. O mesmo não é verdade para endereços Bech32: Se alguém nos disser que não pode enviar para o nosso endereço Bech32 precisaremos gerar um endereço ```legacy``` ou P2SH-SegWit para fazer a transação. (Muitos sites, principalmente as corretoras, também não podem gerar ou receber em endereços SegWit, particularmente endereços Bech32, mas isso é um problema totalmente diferente e não afeta o uso delas). -## Compreendendo uma transação SegWit +## Compreendendo uma Transação SegWit -Em transações clássicas, as informações de assinatura (witness) eram armazenadas no meio da transação, enquanto nas transações SegWit, elas ficavam na parte inferior. Isso anda de mãos dadas com os aumentos de tamanho do bloco que foram introduzidos na atualização do SegWit. O tamanho do bloco foi aumentado de 1 mega para um valor variável com base em quantas transações SegWit estão em um bloco, começando em 1 mega (sem transações SegWit) e podendo chegar a 4 megas (caso todas as transações sejam SegWit). Este tamanho variável foi criado para acomodar os nodes legados, de forma que tudo permaneça compatível com as versões anteriores. Se um node clássico vê uma transação SegWit, ele joga fora as informações da witness (resultando em um bloco de tamanho menor, abaixo do antigo limite de 1 mega), enquanto se um novo node vê uma transação SegWit, ele mantém as informações da witness (resultando em um maior tamanho de bloco, até o novo limite de 4 megas). +Em transações clássicas, as informações de assinatura (witness) eram armazenadas no meio da transação, enquanto nas transações SegWit, elas ficam na parte inferior. Isso anda de mãos dadas com os aumentos de tamanho do bloco que foram introduzidos na atualização do SegWit. O tamanho do bloco foi aumentado de 1 mega para um valor variável com base em quantas transações SegWit estão em um bloco, começando em 1 mega (sem transações SegWit) e podendo chegar a 4 megas (caso todas as transações sejam SegWit). Este tamanho variável foi criado para acomodar os nodes clássicos, de forma que tudo permaneça compatível com as versões anteriores. Se um node clássico vê uma transação SegWit, ele joga fora as informações da witness (resultando em um bloco de tamanho menor, abaixo do antigo limite de 1 mega), enquanto se um novo node vê uma transação SegWit, ele mantém as informações da witness (resultando em um maior tamanho de bloco, até o novo limite de 4 megas). -Portanto, acabamos de responder o quê são e como funcionam as transações SegWit. Não que precisemos saber disso para usá-las. A maioria das transações na rede Bitcoin são SegWit. Elas são aquilo que iremos utilizar nativamente para as transações e recebimentos de bitcoins. Os detalhes não são mais relevantes à partir deste ponto, tanto quanto não são mais relevantes como o Bitcoin funciona. +Portanto, acabamos de responder o quê são e como funcionam as transações SegWit. Não que precisemos saber disso para usá-las. A maioria das transações na rede Bitcoin são SegWit. Elas são aquilo que iremos utilizar nativamente para as transações e recebimentos de bitcoins. A este ponto, os detalhes não são mais relevantes do que os detalhes de como grande parte do Bitcoin funciona. -## Criando um endereço SegWit +## Criando um Endereço SegWit Criamos um endereço SegWit da mesma maneira que qualquer outro endereço, com os comandos ```getnewaddress``` e ```getrawchangeaddress```. @@ -27,14 +27,14 @@ $ bitcoin-cli -named getnewaddress address_type=p2sh-segwit ``` Se conseguirmos ver um endereço com o prefixo "2" significa que fizemos tudo certo. -> :link: **TESTNET vs MAINNET:** "3" no caso da mainnet. +> :link: **TESTNET vs MAINNET:** "3" para a Mainnet. No entanto, se a pessoa com quem estamos interagindo tem um node com uma versão mais nova, ela poderá enviar para um endereço Bech32, que criamos usando os comandos da maneira padrão: ``` $ bitcoin-cli getnewaddress tb1q5gnwrh7ss5mmqt0qfan85jdagmumnatcscwpk6 ``` -Como já vimos, os endereços de troco gerados a partir do ```bitcoin-cli``` interagem bem com os endereços Bech32, então não há motivo nenhum usar o sinalizador ```legacy``` lá também: +Como já vimos, os endereços de troco gerados a partir do ```bitcoin-cli``` interagem bem com os endereços Bech32, então não há motivo nenhum para usar o sinalizador ```legacy``` lá também: ``` $ bitcoin-cli getrawchangeaddress tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff @@ -42,9 +42,9 @@ tb1q05wx5tyadm8qe83exdqdyqvqqzjt3m38vfu8ff Aqui, podemos observar que o prefixo "tb1" exclusivo denota que o endereço é um Bech32. -> :link: ** TESTNET vs MAINNET: ** "bc1" no caso da mainnet. +> :link: **TESTNET vs MAINNET:** "bc1" para a mainnet. -O Bitcoin-cli não se importa com o tipo de endereço que estamos utilizando. Podemos executar um comando como ```listaddressgroupings``` que ele irá misturar os endereços livremente não importando os tipos: +O bitcoin-cli não se importa com o tipo de endereço que estamos utilizando. Podemos executar um comando como ```listaddressgroupings``` que ele irá misturar os endereços livremente, não importando os tipos: ``` $ bitcoin-cli listaddressgroupings [ @@ -109,11 +109,11 @@ $ bitcoin-cli listaddressgroupings ] ``` -## Enviando uma transação SegWit no modo easy +## Enviando uma Transação SegWit da Maneira Fácil -Então, como enviamos uma transação Segwit? Exatamente como qualquer outra transação. Não importa se o UTXO é SegWit, o endereço é SegWit ou alguma combinação dos dois. Podemos ter a certeza que o ```bitcoin-cli``` irá fazer a coisa certa. Embora possamos perceber algumas diferenças nos endereços, eles não importam para interagir com as coisas no nível do ```bitcoin-cli``` ou do RPC. (E esta é uma das vantagens de usar a linha de comando e a interface do RPC, conforme sugerido neste tutorial: Os especialistas já fizeram o trabalho duro para nós, incluindo coisas como enviar para endereços legados e Bech32. Acabamos usando essa funcionalidade para nosso próprio benefício). +Então, como enviamos uma transação Segwit? Exatamente como qualquer outra transação. Não importa se o UTXO é SegWit, o endereço é SegWit ou alguma combinação dos dois. Podemos ter a certeza que o ```bitcoin-cli``` irá fazer a coisa certa. Embora possamos perceber algumas diferenças nos endereços, eles não importam para interagir com as coisas no nível do ```bitcoin-cli``` ou do RPC. (E esta é uma das vantagens de usar a linha de comando e a interface do RPC, conforme sugerido neste tutorial: os especialistas já fizeram o trabalho duro para nós, incluindo coisas como enviar para endereços legacy e Bech32. Acabamos usando essa funcionalidade para nosso próprio benefício). -Aqui está um exemplo de um envio para um endereço SegWit, no modo easy: +Aqui está um exemplo de um envio para um endereço SegWit, da maneira fácil: ``` $ bitcoin-cli sendtoaddress tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx 0.005 854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c1018a58b84559b6e05f42 @@ -202,9 +202,9 @@ $ bitcoin-cli gettransaction txid="854a833b667049ac811b4cf1cad40fa7f8dce8b0f4c10 } } ``` -Na verdade, ambos os ```vouts``` usam endereços Bech32: O nosso destinatário e o endereço de troco gerado automaticamente. +Na verdade, ambos ```vouts``` usam endereços Bech32: o nosso destinatário e o endereço de troco gerado automaticamente. -Mas quando retrocedemos nosso ```vin```, descobrimos que veio de um endereço legado. Isso porque não importa: +Mas quando retrocedemos nosso ```vin```, descobrimos que veio de um endereço legacy. Porque isso não importa: ``` $ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f7439137510249af39f01ee82113a7" { @@ -233,7 +233,7 @@ $ bitcoin-cli -named gettransaction txid="33173618421804343e8f6cc21316d97a24f743 } ``` -## Enviando uma transação SegWit o modo hard +## Enviando uma Transação SegWit da Maneira Difícil Da mesma forma, podemos financiar uma transação com um endereço Bech32, sem nenhuma diferença em relação às técnicas que aprendemos até agora. Aqui está uma maneira exata de fazer isso com uma transação bruta completa: ``` @@ -269,20 +269,20 @@ e02568b706b21bcb56fcf9c4bb7ba63fdbdec1cf2866168c4f50bc0ad693f26c ``` Tudo funciona exatamente da mesma forma que outros tipos de transações! -### Reconhecendo o novo descritor +### Reconhecendo o Novo Descritor -Se olharmos o campo ```desc```, notaremos que o endereço SegWit tem um descritor de estilo diferente daqueles encontrados na sessão [§3.5: Entendendo o descritor](03_5_Understanding_the_Descriptor.md). Um descritor legado descrito nessa sessão se parecia com algo assim: `pkh ([d6043800 / 0 '/ 0' / 18 '] 03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388) # 4ahsl9pk`. Nosso novo descritor SegWit se parece mais com isso: `wpkh ([d6043800 / 0 '/ 0' / 5 '] 0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640) # hd66hknp" `. +Se olharmos o campo ```desc```, notaremos que o endereço SegWit tem um descritor de estilo diferente daqueles encontrados na seção [§3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md). Um descritor legacy descrito nessa seção se parecia com algo assim: `pkh ([d6043800 / 0 '/ 0' / 18 '] 03efdee34c0009fd175f3b20b5e5a5517fd5d16746f2e635b44617adafeaebc388) # 4ahsl9pk`. Nosso novo descritor SegWit se parece mais com isso: `wpkh ([d6043800 / 0 '/ 0' / 5 '] 0327dbe2d58d9ed2dbeca28cd26e18f48aa94c127fa6fb4b60e4188f6360317640) # hd66hknp" `. -A grande diferença que precisamos notar é que a função mudou. Anteriormente, era ```pkh```, que é um endereço padrão de chave pública com hash P2PKH. Ao invés disso, o endereço SegWit é ```wpkh```, o que significa que é um endereço SegWit P2WPKH nativo. Isso dá destaque ao :fire: ***poder dos descritores***. Eles descrevem como criar um endereço a partir de uma chave ou outra informação, com as funções definindo de forma inequívoca como fazer o endereço com base no tipo de cada endereço. +A grande diferença que precisamos notar é que a função mudou. Anteriormente, era ```pkh```, que é um endereço padrão de chave pública com hash P2PKH. Ao invés disso, o endereço SegWit é ```wpkh```, o que significa que é um endereço SegWit P2WPKH nativo. Isto destaca o :fire: ***poder dos descritores***. Eles descrevem como criar um endereço a partir de uma chave ou outra informação, com as funções definindo de forma inequívoca como fazer o endereço com base em seu tipo. -## Resumo do Criando uma transação do tipo SegWit +## Resumo: Criando uma Transação SegWit -Realmente não há complexidade para criar transações SegWit. Internamente, elas são estruturadas de forma diferente das transações legadas, mas na linha de comando não existe diferença: Apesar usamos um endereço com um prefixo diferente. A única coisa a ser observada é que algumas pessoas podem não conseguir enviar para um endereço Bech32 se estiverem usando um software obsoleto. +Realmente não há complexidade para criar transações SegWit. Internamente, elas são estruturadas de forma diferente das transações legacy, mas na linha de comando não existe diferença: apenas usamos um endereço com um prefixo diferente. A única coisa a ser observada é que algumas pessoas podem não conseguir enviar para um endereço Bech32 se estiverem usando um software obsoleto. -> :fire: ***Qual é o poder de criar transações usando o SegWit?*** -> _As vantagens._ As transações do SegWit são menores e, portanto, serão mais baratas de serem enviadas do que as transações legadas devido às taxas mais baixas. O Bech32 diminui essa vantagem e também cria endereços que são mais difíceis de errar durante a transcrição, e isso é muito importante, visto que o erro do usuário é uma das maneiras mais prováveis de terem seus bitcoins perdidos. -> _As desvantagens._ Os endereços SegWit não tem suporte em nodes do Bitcoin obsoleto. Em particular, as pessoas podem não conseguir enviar para o nosso endereço Bech32. +> :fire: ***Qual é o poder de enviar transações com SegWit?*** +> _As vantagens._ As transações SegWit são menores e, portanto, serão mais baratas de serem enviadas do que as transações legacy devido às taxas mais baixas. O Bech32 diminui essa vantagem e também cria endereços que são mais difíceis de errar durante a transcrição, e isso é muito importante, visto que o erro do usuário é uma das maneiras mais prováveis de perderem seus bitcoins. +> _As desvantagens._ Os endereços SegWit não tem suporte em nodes Bitcoin obsoletos. Em particular, as pessoas podem não conseguir enviar para o nosso endereço Bech32. -## O que vem depois? +## O Que Vem Depois? -Vamos avançar mais um pouco no "bitcoin-cli" com o [Capítulo 5: Controlando as transações do Bitcoin](05_0_Controlling_Bitcoin_Transactions.md). \ No newline at end of file +Vamos avançar mais um pouco no "bitcoin-cli" com o [Capítulo 5: Controlando Transações no Bitcoin](05_0_Controlling_Bitcoin_Transactions.md). \ No newline at end of file From 43d0a40d917396f16bf2286df7bebba15152d074 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 19 Jul 2021 13:26:29 -0300 Subject: [PATCH 46/50] Review 06_0 --- ...xpanding_Bitcoin_Transactions_Multisigs.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md index 66cea7e..6bf524f 100644 --- a/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md +++ b/pt/06_0_Expanding_Bitcoin_Transactions_Multisigs.md @@ -1,19 +1,19 @@ -# Capítulo 6: Expandindo as transações de Bitcoin com multisigs +# Capítulo 6: Expandindo Transações no Bitcoin com Multisigs -Transações básicas de Bitcoin: (1) Envia fundos; (2) Para um único destinatário P2PKH ou SegWit; (3) A partir de uma única máquina; (4) Imediatamente. No entanto, todas essas quatro partes desta definição podem ser expandidas usando transações Bitcoin mais complexas. Este primeiro capítulo sobre "Expansão" mostra como variar os pontos (2) e (3), enviando saldos para um endereço que representa vários destinatários (ou, pelo menos, vários assinantes). +Transações básicas no Bitcoin: (1) enviam fundos; (2) para um único destinatário P2PKH ou SegWit; (3) de uma única máquina; (4) imediatamente. No entanto, todas as quatro partes desta definição podem ser expandidas usando transações mais complexas no Bitcoin. Este primeiro capítulo sobre "Expansão" mostra como variar os pontos (2) e (3) enviando saldos para um endereço que representa vários destinatários (ou, pelo menos, vários assinantes). ## Objetivos deste capítulo Depois de trabalhar neste capítulo, um desenvolvedor será capaz de: - * Criar endereços de Bitcoin multi assinados (multisigs) usando os fundamentos do Bitcoin; - * Crie endereços de Bitcoin com várias assinaturas (multisigs) usando mecanismos fáceis. + * Criar endereços de Bitcoin multi-assinatura (multisig) usando os fundamentos do Bitcoin; + * Criar endereços de Bitcoin multi-assinatura (multisig) usando mecanismos mais fáceis. Os objetivos secundários do capítulo incluem a capacidade de: - * Entender como gastar fundos enviados em uma transação multisig; - * Planejar para obter o máximo do poder das multisigs. + * Entender como gastar fundos enviados para um multisig; + * Planejar para obter o máximo do poder dos multisigs. -## Tabela de conteúdo +## Tabela de Conteúdo - * [Seção 1: Enviando uma Transação Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) - * [Seção 2: Gastando uma Transação Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) - * [Seção 3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md) \ No newline at end of file + * [Seção 1: Enviando uma Transação com Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [Seção 2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [Seção 3: Enviando e Gastando um Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md) \ No newline at end of file From bc4705795f024b02ca435fa264c18f3d870508cc Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 19 Jul 2021 15:57:20 -0300 Subject: [PATCH 47/50] Review 06_1 --- ...6_1_Sending_a_Transaction_to_a_Multisig.md | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/pt/06_1_Sending_a_Transaction_to_a_Multisig.md b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md index f54d828..e9c3f57 100644 --- a/pt/06_1_Sending_a_Transaction_to_a_Multisig.md +++ b/pt/06_1_Sending_a_Transaction_to_a_Multisig.md @@ -1,24 +1,24 @@ -# 6.1: Enviando uma Transação Multsig +# 6.1: Enviando uma Transação com Multisig -A primeira maneira de variar a forma como enviamos uma transação básica é usando uma multisig. Isso nos dá a capacidade de exigir que várias pessoas (ou, ao menos, várias chaves privadas) autorizem o uso dos fundos. +A primeira maneira de variar a forma como enviamos uma transação básica é usando um multisig. Isso nos dá a capacidade de exigir que várias pessoas (ou, ao menos, várias chaves privadas) autorizem o uso dos fundos. -## Entendendo como Funcionam as Multisigs +## Entendendo como Funcionam os Multisigs Em uma transação P2PKH ou SegWit padrão, os bitcoins são enviados para um endereço baseado na chave pública, o que significa que a chave privada relacionada é necessária para desbloquear a transação, resolvendo o quebra-cabeça criptográfico e permitindo que reutilizemos o saldo. Mas e se pudéssemos bloquear uma transação com _múltiplas_ chaves privadas? Isso efetivamente permitiria que os fundos fossem enviados a um grupo de pessoas, onde todas teriam que concordar em reutilizar o saldo. -> :book: ***O que é uma multisignature ou multisig?*** Uma _multisignature_ é uma metodologia que permite que mais de uma pessoa crie uma assinatura digital em conjunto. É uma técnica para o uso criptográfico de chaves que vai muito além do Bitcoin. +> :book: ***O que é uma multi-assinatura?*** Uma multi-assinatura é uma metodologia que permite que mais de uma pessoa crie uma assinatura digital em conjunto. É uma técnica geral para o uso criptográfico de chaves que vai muito além do Bitcoin. -Tecnicamente, um quebra-cabeça criptográfico com várias assinaturas é criado pelo Bitcoin usando o comando OP_CHECKMULTISIG e, normalmente, é encapsulado em um endereço P2SH. A seção [§10.4: Fazendo um scripto multisig](10_4_Scripting_a_Multisig.md) irá detalhar como isso funciona com mais precisão. Por enquanto, tudo que precisamos saber é que podemos usar o comando ```bitcoin-cli``` para criar endereços multi assinados. Os fundos podem ser enviados para esses endereços como qualquer endereço P2PKH ou Segwit normal, mas várias chaves privadas serão necessárias para que o saldo seja enviado. +Tecnicamente, um quebra-cabeça criptográfico com várias assinaturas é criado pelo Bitcoin usando o comando OP_CHECKMULTISIG e, normalmente, é encapsulado em um endereço P2SH. A seção [§10.4: Programando um Multisig](10_4_Scripting_a_Multisig.md) irá detalhar como isso funciona com mais precisão. Por enquanto, tudo que precisamos saber é que podemos usar o comando ```bitcoin-cli``` para criar endereços multi-assinatura. Os fundos podem ser enviados para esses endereços como qualquer endereço P2PKH ou Segwit normal, mas várias chaves privadas serão necessárias para que o saldo seja resgatado. -> :book: ***O que é uma transação multisig?*** Uma transação com várias assinaturas é uma transação Bitcoin enviada para um endereço com várias assinaturas, exigindo assim que as pessoas de um grupo com várias assinaturas precisem assinar a transação para poder ter acesso ao saldo. +> :book: ***O que é uma transação multisig?*** Uma transação multisig é uma transação no Bitcoin enviada para um endereço com várias assinaturas, exigindo assim que certas pessoas do grupo multi-assinatura precisem assinar a transação para poder reutilizar o saldo. -As multisigs simples exigem que todos no grupo assinem o UTXO quando estiver gasto. No entanto, há mais complexidade possível. As assinaturas múltiplas são geralmente descritas como sendo "M de N". Isso significa que a transação está presa com um grupo de chaves "N", mas apenas "M" delas são necessárias para desbloquear a transação. +Multisigs simples exigem que todos no grupo assinem o UTXO quando for gasto. No entanto, há mais complexidade possível. Multisigs são geralmente descritos como sendo "m de n". Isso significa que a transação está trancada com um grupo de chaves "n", mas apenas "m" delas são necessárias para desbloquear a transação. -> :book: ***O que é uma multisg M-de-N? *** Em uma multisig, as assinaturas "M" de um grupo de "N" são necessárias para formar a assinatura, onde "M ≤ N". +> :book: ***O que é um multisg m-de-n?*** Em um multisig, "m" assinaturas de um grupo de "n" são necessárias para formar a assinatura, onde "m ≤ n". ## Criando um Endereço Multisig -Para bloquear um UTXO com várias chaves privadas, devemos primeiro criar um endereço com várias assinaturas. Os exemplos usados ​​aqui mostram a criação (e uso) de uma multisig 2 de 2 (normalmente é assim que falamos quando nos referimos a um endereço multisg, descrevemos a quantidade de chaves e a quantidade necessária para desbloquear o saldo). +Para trancar um UTXO com várias chaves privadas, devemos primeiro criar um endereço multi-assinatura. Os exemplos usados ​​aqui mostram a criação (e uso) de um multisig 2-de-2. ### Criando os Endereços @@ -32,13 +32,13 @@ machine2$ address2=$(bitcoin-cli getnewaddress) ``` Posteriormente, um dos destinatários (ou talvez algum terceiro) precisará combinar ambos endereços. -#### Coletando as Chaves Públicas +#### Coletando Chaves Públicas No entanto, não podemos criar um multisig com os endereços, pois esses são os hashes das chaves públicas: Ao invés disso, precisamos das próprias chaves públicas. Esta informação está disponível facilmente com o comando ```getaddressinfo```. -Na máquina remota, que assumimos aqui é ```machine2```, podemos obter as informações em uma lista. +Na máquina remota, que assumimos aqui que é ```machine2```, podemos obter as informações em uma lista. ``` machine2$ bitcoin-cli -named getaddressinfo address=$address2 { @@ -65,9 +65,9 @@ machine2$ bitcoin-cli -named getaddressinfo address=$address2 ``` O endereço ```pubkey``` (` 02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3`) é o que precisamos. Vamos copiá-lo para nossa máquina local por qualquer meio que acharmos mais eficiente e _que seja menos sujeito a erros_. -Este processo precisa ser realizado para _cada_ endereço de uma máquina diferente daquela onde o multisig está sendo construída. Obviamente, se algum terceiro estiver criando o endereço, precisaremos fazer isso para cada endereço. +Este processo precisa ser realizado para _cada_ endereço de uma máquina diferente daquela onde o multisig está sendo construído. Obviamente, se algum terceiro estiver criando o endereço, precisaremos fazer isso para cada endereço. -> :warning: **Atenção:** O uso de hashes de chave pública pelo Bitcoin como endereços, ao invés de chaves públicas, na verdade representa uma camada adicional de segurança. Porém, o envio de uma chave pública aumenta ligeiramente a vulnerabilidade do endereço associado, para alguma possibilidade no futuro distante de um comprometimento devido a curva elíptica. Não devemos nos preocupar em termos que enviar ocasionalmente uma chave pública para um uso como esse, mas devemos estar cientes de que os hashes de chave pública representam segurança e, portanto, as chaves públicas reais não devem ser enviadas de qualquer jeito para qualquer pessoa. +> :warning: **ATENÇÃO:** O uso de hashes de chave pública pelo Bitcoin como endereços, ao invés de chaves públicas, na verdade representa uma camada adicional de segurança. Portanto, o envio de uma chave pública aumenta ligeiramente a vulnerabilidade do endereço associado, devido a alguma possibilidade do comprometimento da curva elíptica em um futuro distante. Não devemos nos preocupar em termos que enviar ocasionalmente uma chave pública para um uso como esse, mas devemos estar cientes de que os hashes de chave pública representam segurança e, portanto, as chaves públicas reais não devem ser enviadas de qualquer jeito para qualquer pessoa. Se um dos endereços foi criado em nossa máquina local, que assumimos aqui que seja ```machine1```, podemos simplesmente colocar o endereço ```pubkey``` em uma nova variável. ``` @@ -76,7 +76,7 @@ machine1$ pubkey1=$(bitcoin-cli -named getaddressinfo address=$address1 | jq -r ### Criando o Endereço -Uma multisig agora pode ser criada com o comando ```createmultisig```: +Um multisig agora pode ser criado com o comando ```createmultisig```: ``` machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3"]''' { @@ -87,36 +87,36 @@ machine1$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","0 ``` > :warning: **AVISO DE VERSÃO:** Algumas versões do ```createmultisig``` permitem a entrada de chaves públicas ou endereços, algumas requerem apenas as chaves públicas. Atualmente, ambas parecem funcionar. -Ao criar o endereço multisig, listamos quantas assinaturas são necessárias com o argumento ```nrequired``` (que é o "M" quando falamos _uma multisig "M de N"_), então listamos o conjunto total de assinaturas possíveis com a argumento ```keys``` (que é o "N"). Observe que as entradas ```keys``` provavelmente vieram de lugares diferentes. Nesse caso, incluímos ```$pubkey1``` da máquina local e ```02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3``` de uma máquina remota. +Ao criar o endereço multisig, listamos quantas assinaturas são necessárias com o argumento ```nrequired``` (que é o "m" em um multisig "m-de-n"), então listamos o conjunto total de assinaturas possíveis com a argumento ```keys``` (que é o "n"). Observe que as entradas ```keys``` provavelmente vieram de lugares diferentes. Nesse caso, incluímos ```$pubkey1``` da máquina local e ```02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3``` de uma máquina remota. -> :information_source: **NOTA - M de N vs N de N:** Este exemplo mostra a criação de um multisig simples 2 de 2 . Se quisermos criar uma assinatura M de N onde "M :information_source: **NOTA –– M-DE-N VS N-DE-N:** Este exemplo mostra a criação de um multisig simples 2-de-2 . Se quisermos criar uma assinatura m-de-n onde "m < n", precisamos apenas ajustar o campo ```nrequired``` e/ou o número de assinaturas ```keys``` no objeto JSON. Para um multisig 1-de-2, seria definido como ```nrequired = 1``` e também listaria duas chaves, enquanto para um multisig 2-de-3, seria necessário um ```nrequired = 2```, mas adicionaria mais uma chave pública à lista de ```keys```. Quando usado corretamente, o ```createmultisig``` retorna três resultados, todos criticamente importantes. O _endereço_ é o que iremos distribuir para as pessoas que desejam enviar os fundos. Podemos notar que ele tem um novo prefixo ```2```, exatamente como os endereços P2SH-SegWit. Isso porque, como eles, o comando ```createmultisig``` está na verdade criando um tipo de endereço totalmente novo chamado endereço P2SH. Ele funciona exatamente como um endereço P2PKH padrão para envio de fundos, mas como este foi criado para exigir vários endereços, precisaremos trabalhar um pouco mais para utilizá-los. -> :link: **TESTNET vs MAINNET:** Na Testenet, o prefixo para endereços P2SH é ```2```, enquanto na Mainnet é ```3```. +> :link: **TESTNET vs MAINNET:** Na testenet, o prefixo para endereços P2SH é ```2```, enquanto na Mainnet é ```3```. -O _redeemScript_ é o que precisaremos para resgatar os fundos (junto com as chaves privadas de "M" dos "N" endereços). Este script é outro recurso especial dos endereços P2SH e será explicado com mais detalhes na seção [§8.1: Construindo um Script Bitcoin com P2SH](08_1_Building_a_Bitcoin_Script_with_P2SH.md). Por enquanto, precisamos apenas saber que alguns dados são necessários para podemos gastar nosso dinheiro. +O _redeemScript_ é o que precisaremos para resgatar os fundos (junto com as chaves privadas de "m" dos "n" endereços). Este script é outro recurso especial dos endereços P2SH e será explicado com mais detalhes na seção [§10.3: Rodando um Script no Bitcoin com P2SH](10_3_Running_a_Bitcoin_Script_with_P2SH.md). Por enquanto, precisamos apenas saber que alguns dados são necessários para podemos gastar nosso dinheiro. -O _descritor_ é a descrição padronizada para um endereço que encontramos na seção [§3.5: Compreendendo o descriptor](03_5_Understanding_the_Descriptor.md). Ele fornece uma maneira de importar esse endereço de volta para a outra máquina, usando o RPC ```importmulti```. +O _descritor_ é a descrição padronizada para um endereço que encontramos na seção [§3.5: Compreendendo o Descritor](03_5_Understanding_the_Descriptor.md). Ele fornece uma maneira de importar esse endereço de volta para a outra máquina, usando o RPC ```importmulti```. -> :book: ***O que é um endereço P2SH?*** O P2SH significa Pay-To-Script-Hash. É um tipo de destinatário diferente de um endereço P2PKH padrão ou mesmo de um Bech32, usado para fundos cujo resgate é baseado em scripts de Bitcoin mais complexos. O ```bitcoin-cli``` usa o encapsulamento P2SH para ajudar a padronizar e simplificar os multisigs como "multisigs P2SH ", assim como P2SH-SegWit estava usando o P2SH para padronizar os endereços SegWit e torná-los totalmente compatíveis com as versões legadas. +> :book: ***O que é um endereço P2SH?*** O P2SH significa Pay-To-Script-Hash. É um tipo de destinatário diferente de um endereço P2PKH padrão ou mesmo de um Bech32, usado para fundos cujo resgate é baseado em scripts de Bitcoin mais complexos. O ```bitcoin-cli``` usa o encapsulamento P2SH para ajudar a padronizar e simplificar os multisigs como "multisigs P2SH", assim como P2SH-SegWit estava usando o P2SH para padronizar os endereços SegWit e torná-los totalmente compatíveis com as versões antigas. -> :warning: **Atenção:** endereços P2SH multisig, como os criados pelo ```bitcoin-cli```, têm um limite para "M" e "N" nos multisigs com base no tamanho máximo do script de resgate, que atualmente é de 520 bytes. Praticamente, não vamos chegar a isso, a menos que estejamos nos excedendo em algo. +> :warning: **ATENÇÃO:** endereços P2SH multisig, como os criados pelo ```bitcoin-cli```, têm um limite para "m" e "n" nos multisigs com base no tamanho máximo do script de resgate, que atualmente é de 520 bytes. Praticamente, não vamos chegar a isso, a menos que estejamos nos excedendo em algo. ### Salvando Nosso Trabalho -Aqui está uma informação importante: Nada sobre nosso multisig é salvo em nossa carteira usando essas técnicas básicas. Para resgatar o saldo enviado para este endereço multisig no futuro, precisaremos reter duas informações cruciais: +Aqui está uma informação importante: nada sobre nosso multisig é salvo em nossa carteira usando essas técnicas básicas. Para resgatar o saldo enviado para este endereço multisig no futuro, precisaremos reter duas informações cruciais: * Uma lista dos endereços Bitcoin usados ​​no multisig, e; * A saída ```redeemScript``` criada pelo comando ```createmultsig```. -Tecnicamente, o ```redeemScript``` pode ser recriado executando novamente o ```createmultisig``` com a lista completa de chaves públicas _na mesma ordem_ e com a contagem correta de M e de N. Mas, é melhor agarrar-se a ela e evitar qualquer tipo de estresse futuro. +Tecnicamente, o ```redeemScript``` pode ser recriado executando novamente o ```createmultisig``` com a lista completa de chaves públicas _na mesma ordem_ e com a contagem m-de-n correta. Mas, é melhor agarrar-se a ela e evitar qualquer tipo de estresse futuro. -### Observando a Ordem +### Observe a Ordem -Aqui está mais uma coisa que devemos tomar muito cuidado: A _ordem é muito importante_. A ordem das chaves usadas para criar um multisig cria um hash único, ou seja, se colocarmos as chaves em uma ordem diferente, elas irão produzir um endereço diferente, conforme mostrado abaixo: +Aqui está mais uma coisa que devemos tomar muito cuidado: _a ordem importa_. A ordem das chaves usadas para criar um multisig cria um hash único, ou seja, se colocarmos as chaves em uma ordem diferente, elas irão produzir um endereço diferente, conforme mostrado abaixo: ``` $ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$pubkey1'","'$pubkey2'"]''' { @@ -131,11 +131,11 @@ standup@btctest20:~$ bitcoin-cli -named createmultisig nrequired=2 keys='''["'$p "descriptor": "sh(multi(2,039cd6842869c1bfec13cfdbb7d8285bc4c501d413e6633e3ff75d9f13424d99b3,0342b306e410283065ffed38c3139a9bb8805b9f9fa6c16386e7ea96b1ba54da03))#audl88kg" } ``` -Mais notavelmente, cada ordem cria um _redeemScript_ diferente. Isso significa que se usamos essas técnicas básicas e não conseguimos salvar o redemScript conforme as instruções, teremos que percorrer um número cada vez maior de variações para encontrar aquela correta quando tentarmos gastar os fundos! +Mais notavelmente, cada ordem cria um _redeemScript_ diferente. Isso significa que se usamos essas técnicas básicas e não salvarmos o redemScript conforme as instruções, teremos que percorrer um número cada vez maior de variações para encontrar a correta quando tentarmos gastar os fundos! -O [BIP67](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) sugere uma maneira de ordenar lexicograficamente as chaves, de modo que sempre gerem as mesmas multisigs. A ColdCard e a Electrum estão entre as carteiras que já possuem suporte a isso. Claro, isso pode causar problemas por si só se não soubermos se um endereço multisig foi criado com chaves classificadas ou não classificadas. Mais uma vez, os [descritores](03_5_Understanding_the_Descriptor.md) vem ao nosso resgate. Se uma multisig não for classificada, ele será construído com a função ```multi``` e se for classificada, será construída com a função ```sortedmulti```. +O [BIP67](https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki) sugere uma maneira de ordenar lexicograficamente as chaves, de modo que sempre gerem as mesmas multisigs. A ColdCard e a Electrum estão entre as carteiras que já possuem suporte a isso. Claro, isso pode causar problemas por si só se não soubermos se um endereço multisig foi criado com chaves classificadas ou não classificadas. Mais uma vez, os [descritores](03_5_Understanding_the_Descriptor.md) vêm ao nosso resgate. Se um multisig não for classificado, ele será construído com a função ```multi```, e se for classificado, será construído com a função ```sortedmulti```. -Se olharmos o ```desc``` da multisig que criamos acima, veremos que o Bitcoin Core atualmente não classifica os multisigs: +Se olharmos o ```desc``` do multisig que criamos acima, veremos que o Bitcoin Core atualmente não classifica os multisigs: ``` "descriptor": "sh(multi(2,02da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d191,02bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa3))#0pazcr4y" ``` @@ -143,9 +143,9 @@ Porém, se ele importa um endereço do tipo ```sortedmulti```, ele fará o proce > :warning: **AVISO DE VERSÃO:** O Bitcoin Core só entende a função do descritor ```sortedmulti``` após a versão 0.20.0. Podemos tentar acessar o descritor em uma versão anterior do Bitcoin Core e obteremos um erro como ```A function is needed within P2WSH```. -## Enviando Fundos para um Endereço Multisig +## Enviando para um Endereço Multisig -Se tivermos uma multisig em um formato P2SH conveniente, como o gerado pelo ```bitcoin-cli```, podemos enviar como um endereço normal. +Se tivermos um multisig em um formato P2SH conveniente, como o gerado pelo ```bitcoin-cli```, podemos enviar como um endereço normal. ``` $ utxo_txid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid') $ utxo_vout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout') @@ -195,12 +195,12 @@ b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 ``` Como podemos ver, não houve nada de incomum na criação da transação e ela parece normal, embora com um endereço com um prefixo diferente do normal (```2N8MytPW2ih27LctLjn6LfLFZZb1PFSsqBr```). Sem surpresa, como também não vimos diferença quando enviamos para endereços Bech32 pela primeira vez na seção [§4.6](04_6_Creating_a_Segwit_Transaction.md). -## Resumo: Enviando uma Transação Multsig +## Resumo: Enviando uma Transação Multisig -Os endereços do Multisig trancam os fundos usando várias chaves privadas, possivelmente exigindo todas essas chaves privadas para resgate e, possivelmente, exigindo apenas algumas do conjunto. Eles são fáceis de serem criadas com o ```bitcoin-cli``` e são simples para serem enviadas. Essa facilidade se deve em grande parte ao uso invisível de endereços P2SH (Pay-To-Script-Hash), um tópico extenso que já falamos duas vezes, com endereços P2SH-SegWit e agora com as multisig, e um outro que receberá mais atenção no futuro. +Os endereços multisig trancam os fundos usando várias chaves privadas, possivelmente exigindo todas essas chaves privadas para resgate e, possivelmente, exigindo apenas algumas do conjunto. Eles são fáceis de serem criados com o ```bitcoin-cli``` e são simples para serem enviados. Essa facilidade se deve em grande parte ao uso invisível de endereços P2SH (Pay-To-Script-Hash), um tópico extenso que já falamos duas vezes, com endereços P2SH-SegWit e agora com os multisigs, e um outro que receberá mais atenção no futuro. -> :fire: ***Qual é o poder das multisig?*** As multisig permitem a modelagem de uma variedade de arranjos financeiros, como corporações, parcerias, comitês e outros grupos. Uma multisig 1 de 2 pode ser a conta bancária conjunta de um casal, enquanto uma multisig 2 de 2 pode ser usado para grandes despesas por uma parceria de responsabilidade limitada. As multisigs também constituem uma das bases dos Smart Contracts. Por exemplo, um negócio imobiliário pode ser fechado com um multisig 2 de 3, onde as assinaturas são enviadas pelo comprador, pelo vendedor e por um agente de custódia. Depois que o agente de custódia concorda que todas as condições foram atendidas, ele libera os fundos para o vendedor, ou, alternativamente, o comprador e o vendedor podem liberar os fundos em conjunto. +> :fire: ***Qual é o poder das multi-assinaturas?*** As multi-assinaturas permitem a modelagem de uma variedade de arranjos financeiros, como corporações, parcerias, comitês e outros grupos. Um multisig 1-de-2 pode ser a conta bancária conjunta de um casal, enquanto um multisig 2-de-2 pode ser usado para grandes despesas por uma parceria de responsabilidade limitada. Os multisigs também constituem uma das bases dos Smart Contracts. Por exemplo, um negócio imobiliário pode ser fechado com um multisig 2-de-3, onde as assinaturas são enviadas pelo comprador, pelo vendedor e por um agente de custódia. Depois que o agente de custódia concorda que todas as condições foram atendidas, ele libera os fundos para o vendedor, ou, alternativamente, o comprador e o vendedor podem liberar os fundos em conjunto. ## O Que Vem Depois? -Vamos continuar "Expandindo as transações de Bitcoin com multisigs" na seção [§6.2: Gastando uma transação Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md). \ No newline at end of file +Vamos continuar "Expandindo Transações no Bitcoin com Multisigs" na seção [§6.2: Gastando uma Transação com Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md). \ No newline at end of file From d5fb91ac00fb1b39913eed8c054b45b8065ef080 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 19 Jul 2021 15:58:44 -0300 Subject: [PATCH 48/50] Fix typos --- pt/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pt/README.md b/pt/README.md index cd3ef49..2917302 100644 --- a/pt/README.md +++ b/pt/README.md @@ -52,8 +52,8 @@ Se você gostaria de fazer a sua própria tradução, por favor veja [Contribuin * [5.2: Re-enviando uma Transação com RBF](05_2_Resending_a_Transaction_with_RBF.md) * [5.3: Financiando uma Transação com CPFP](05_3_Funding_a_Transaction_with_CPFP.md) * [6.0: Expandindo Transações no Bitcoin com Multisigs](06_0_Expanding_Bitcoin_Transactions_Multisigs.md) - * [6.1: Enviando uma Transação com Multsig](06_1_Sending_a_Transaction_to_a_Multisig.md) - * [6.2: Gastando uma Transação com Multsig](06_2_Spending_a_Transaction_to_a_Multisig.md) + * [6.1: Enviando uma Transação com Multisig](06_1_Sending_a_Transaction_to_a_Multisig.md) + * [6.2: Gastando uma Transação com Multisig](06_2_Spending_a_Transaction_to_a_Multisig.md) * [6.3: Enviando & Gastando um Multisig Automatizado](06_3_Sending_an_Automated_Multisig.md) * [7.0: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md) * [7.1: Criando uma Transação Parcialmente Assinada no Bitcoin (PSBT)](07_1_Creating_a_Partially_Signed_Bitcoin_Transaction.md) From 9ec21b57cd789f2335dbb7e8f45028670ccd2107 Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 19 Jul 2021 16:20:58 -0300 Subject: [PATCH 49/50] Review 06_2 --- ..._2_Spending_a_Transaction_to_a_Multisig.md | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/pt/06_2_Spending_a_Transaction_to_a_Multisig.md b/pt/06_2_Spending_a_Transaction_to_a_Multisig.md index f916780..8114969 100644 --- a/pt/06_2_Spending_a_Transaction_to_a_Multisig.md +++ b/pt/06_2_Spending_a_Transaction_to_a_Multisig.md @@ -1,8 +1,8 @@ -# 6.2: Gastando uma Transação Multsig +# 6.2: Gastando uma Transação com Multsig A maneira clássica e complexa de gastar fundos enviados para um endereço com várias assinaturas usando o ```bitcoin-cli``` requer que suemos bastante a camisa. -## Encontrando os fundos +## Encontrando os Fundos Para começar, precisamos encontrar nossos fundos. Nosso computador não sabe procurá-los, porque não estão associados a nenhum endereço da nossa carteira. Podemos alertar o ```bitcoind``` para fazer isso usando o comando ```importaddress```: ``` @@ -93,25 +93,25 @@ $ bitcoin-cli -named gettransaction txid=b164388854f9701051809eed166d9f6cedba923 } ``` -## Configurando as nossas variáveis +## Configurando as Nossas Variáveis -Quando estivermos prontos para gastar os fundos recebidos por um endereço multisig, precisaremos coletar _muitos_ dados: Muito mais do que precisamos quando fazemos uma transação usando um UTXO de um P2PKH normal ou SegWit. Isso ocorre em parte porque as informações sobre o endereço multisig não estão em nossa posse e em parte porque estamos gastando dinheiro que foi enviado para um endereço P2SH (Pay-To-Script-Hash) e isso é muito mais exigente. +Quando estivermos prontos para gastar os fundos recebidos por um endereço multisig, precisaremos coletar _muitos_ dados: muito mais do que precisamos quando fazemos uma transação usando um UTXO de um P2PKH normal ou SegWit. Isso ocorre em parte porque as informações sobre o endereço multisig não estão em nossa posse e em parte porque estamos gastando dinheiro que foi enviado para um endereço P2SH (Pay-To-Script-Hash) e isso é muito mais exigente. -No total, precisaremos coletar três coisas: Informações estendidas sobre o UTXO; O redemScript e; Todas as chaves privadas envolvidas. Obviamente, também iremos precisar de um novo endereço de destinatário. As chaves privadas precisam aguardar a etapa de assinatura, mas tudo pode ser feito agora. +No total, precisaremos coletar três coisas: informações estendidas sobre o UTXO; o redemScript e; todas as chaves privadas envolvidas. Obviamente, também iremos precisar de um novo endereço de destinatário. As chaves privadas precisam aguardar a etapa de assinatura, mas tudo pode ser feito agora. -### Acessando as informações do UTXO +### Acessando as Informações do UTXO Para começar, vamos pegar o ```txid``` e o ```vout``` para a transação que desejamos gastar, como de costume. Nesse caso, os dados foram recuperados das informações ```gettransaction``` acima: ``` $ utxo_txid=b164388854f9701051809eed166d9f6cedba92327e4296bf8a265a5da94f6521 $ utxo_vout=0 ``` -No entanto, precisamos também acessar um terceiro bit de informação sobre o UTXO, nosso ```scriptPubKey```/```hex```, que é o script que travamos a transação. Novamente, podemos fazer isso observando os detalhes da transação: +No entanto, precisamos também acessar um terceiro pedaço de informação sobre o UTXO, nosso ```scriptPubKey```/```hex```, que é o script que travou a transação. Novamente, podemos fazer isso observando os detalhes da transação: ``` $ utxo_spk=a914a5d106eb8ee51b23cf60d8bd98bc285695f233f387 ``` -### Gravando o script de resgate +### Gravando o Script de Resgate Felizmente, salvamos nosso ```redeemScript```. Agora devemos registrá-lo em uma variável. @@ -119,13 +119,13 @@ O valor foi extraído da criação de endereço na seção anterior. ``` redeem_script="522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352ae" ``` -### Decidindo o destinatário +### Decidindo o Destinatário Vamos apenas enviar o dinheiro de volta para nós mesmos. Isso é útil porque libera os fundos do multisig, convertendo-os em uma transação P2PKH normal que pode ser posteriormente confirmada por uma única chave privada: ``` $ recipient=$(bitcoin-cli getrawchangeaddress) ``` -## Criando nossa transação +## Criando Nossa Transação Agora podemos criar nossa transação. Essa parte é parecida com as transações normais. ``` @@ -134,22 +134,22 @@ $ echo $rawtxhex 020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b10000000000ffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 ``` -## Assinando a nossa transação +## Assinando Nossa Transação Agora estamos prontos para assinar a transação. Este é um processo de várias etapas porque precisaremos fazer em várias máquinas, cada uma das quais contribuirá com suas próprias chaves privadas. -### Carregando a primeira chave privada +### Carregando a Primeira Chave Privada Como essa transação não está fazendo uso total da nossa carteira, precisaremos acessar diretamente as chaves privadas. Começando com a ```máquina1```, onde devemos recuperar qualquer uma das chaves privadas do usuário que estavam envolvidas no multisig: ``` machine1$ bitcoin-cli -named dumpprivkey address=$address1 cNPhhGjatADfhLD5gLfrR2JZKDE99Mn26NCbERsvnr24B3PcSbtR ``` -> :warning: **Atenção:** Acessar diretamente as chaves privadas do shell é um comportamento muito perigoso e deve ser feito com extremo cuidado se estivermos em um ambiente produtivo. No mínimo, é importante não salvar as informações em uma variável que possa ser acessada pela nossa máquina. Remover o histórico do shell é outro grande passo. No máximo, podemos evitar de fazer isso. +> :warning: **ATENÇÃO:** Acessar diretamente as chaves privadas do shell é um comportamento muito perigoso e deve ser feito com extremo cuidado se estivermos usando dinheiro de verdade. No mínimo, é importante não salvar as informações em uma variável que possa ser acessada pela nossa máquina. Remover o histórico do shell é outro grande passo. No máximo, podemos evitar de fazer isso. -### Fazendo a nossa primeira assinatura +### Fazendo Nossa Primeira Assinatura -Agora podemos fazer nossa primeira assinatura com o comando ```signrawtransactionwithkey```. É aqui que as coisas ficam diferentes das normais: Precisaremos treinar o comando sobre como assinar. Podemos fazer isso adicionando as seguintes informações novas: +Agora podemos fazer nossa primeira assinatura com o comando ```signrawtransactionwithkey```. É aqui que as coisas ficam diferentes: precisaremos treinar o comando sobre como assinar. Podemos fazer isso adicionando as seguintes informações novas: * Incluir um argumento ```prevtxs``` que tenha o ```txid```, o ```vout```, o ```scriptPubKey``` e o ```redeemScript``` que gravamos, cada um deles um par individual do valor-chave no objeto JSON. * Incluir um argumento ```privkeys``` que lista as chaves privadas que pegamos nesta máquina. @@ -175,18 +175,18 @@ machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=$rawtxhex prevt ``` Isso produz erros assustadores e mostra um status de ```failing```. Tudo bem. Podemos ver que a assinatura foi parcialmente bem-sucedida porque o ```hex``` ficou mais longo. Embora a transação tenha sido parcialmente assinada, ela não foi concluída porque precisa de mais assinaturas. -### Repetindo para os outros assinantes +### Repetindo para os Outros Assinantes -Agora podemos passar a transação adiante, para ser assinada novamente por nós, que temos a outra parte da multisig. Eles fazem isso executando o mesmo comando de assinatura que fizemos, porém: (1) com o ```hex``` maior que produzimos anteriormente (```bitcoin-cli -named signrawtransactionwithkey hexstring = $ rawtxhex prevtxs = '' '[{"txid": " '$ utxo_txid'", "vout": '$ utxo_vout', "scriptPubKey": " '$ utxo_spk'", "redeemScript": " '$ redeem_script'"}] '' 'privkeys =' [ "cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"] '| jq -r'. | .hex'```) e; (2) com nossa própria chave privada. +Agora podemos passar a transação adiante, para ser assinada novamente por outros exigidos pelo multisig. Eles fazem isso executando o mesmo comando de assinatura que fizemos, porém: (1) com o ```hex``` maior que produzimos anteriormente (```bitcoin-cli -named signrawtransactionwithkey hexstring = $ rawtxhex prevtxs = '' '[{"txid": " '$ utxo_txid'", "vout": '$ utxo_vout', "scriptPubKey": " '$ utxo_spk'", "redeemScript": " '$ redeem_script'"}] '' 'privkeys =' [ "cMgb3KM8hPATCtgMKarKMiFesLft6eEw3DY6BB8d97fkeXeqQagw"] '| jq -r'. | .hex'```) e; (2) com sua própria chave privada. -> :information_source: **NOTA - M de N vs N de N:** Obviamente, se tivermos uma assinatura N de N (como a multisig 2 de 2 do exemplo), todas as partes precisarão assinar, mas se tiviermos uma multisignatura M de N onde "M :information_source: **NOTA - M-DE-N VS N-DE-N:** Obviamente, se tivermos uma assinatura N de N (como a multisig 2-de-2 do exemplo), todas as partes precisarão assinar, mas se tivermos uma multi-assinatura m-de-n onde "m < n", a assinatura estará completa quando apenas alguns ("m") tiverem assinado. -Para fazer isso, primeiro acessamos as chaves privadas: +Para fazer isso, primeiro eles acessam suas chaves privadas: ``` machine2$ bitcoin-cli -named dumpprivkey address=$address2 cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz ``` -Depois, assinamos o novo ```hex``` usando os mesmos valores ```prevtxs```: +Depois, assinam o novo ```hex``` usando os mesmos valores ```prevtxs```: ``` machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=020000000121654fa95d5a268abf96427e3292baed6c9f6d16ed9e80511070f954883864b100000000920047304402201c97b48215f261055e41b765ab025e77a849b349698ed742b305f2c845c69b3f022013a5142ef61db1ff425fbdcdeb3ea370aaff5265eee0956cff9aa97ad9a357e3010047522102da2f10746e9778dd57bd0276a4f84101c4e0a711f9cfd9f09cde55acbdd2d1912102bfde48be4aa8f4bf76c570e98a8d287f9be5638412ab38dede8e78df82f33fa352aeffffffff0188130000000000001600142c48d3401f6abed74f52df3f795c644b4398844600000000 prevtxs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout', "scriptPubKey": "'$utxo_spk'", "redeemScript": "'$redeem_script'" } ]''' privkeys='["cVhqpKhx2jgfLUWmyR22JnichoctJCHPtPERm11a2yxnVFKWEKyz"]' { @@ -194,11 +194,11 @@ machine1$ bitcoin-cli -named signrawtransactionwithkey hexstring=02000000012165 "complete": true } ``` -Por fim, podemos precisar enviar uma ```hexstring``` ainda mais longa que produzem para assinaturas adicionais. +Por fim, podem precisar enviar uma ```hexstring``` ainda mais longa que eles tenham produzido para assinantes adicionais. Mas, neste caso, podemos ver que a assinatura está `complete`! -## Enviando nossa transação +## Enviando Nossa Transação Quando terminarmos, devemos recorrer à metodologia ```JQ``` padrão para salvar nossa ```hexstring``` e, em seguida, enviá-la: ``` @@ -207,9 +207,9 @@ $ bitcoin-cli -named sendrawtransaction hexstring=$signedtx 99d2b5717fed8875a1ed3b2827dd60ae3089f9caa7c7c23d47635f6f5b397c04 ``` -## Compreendendo a importância desta metodologia de assinatura expandida +## Compreendendo a Importância Desta Metodologia de Assinatura Expandida -Isso deu um belo trabalho e, como logo iremos aprender, existe uma tolice ao utilizar as chaves privadas, o redeem script e com a scriptpubkey pois eles não são realmente necessários para resgatar os endereços de multisg usando versões mais recentes do Bitcoin Core. Então qual era a questão? +Isto deu um belo trabalho e, como logo iremos aprender, existe uma tolice ao utilizar as chaves privadas, o redeem script e com a scriptpubkey pois eles não são realmente necessários para resgatar os endereços de multisg usando versões mais recentes do Bitcoin Core. Então, qual foi o ponto? Esta metodologia de resgate mostra uma maneira padrão de assinar e reutilizar transações P2SH. Em suma, para resgatar fundos P2SH, uma ```signrawtransactionwithkey``` precisa: @@ -220,10 +220,10 @@ Esta metodologia de resgate mostra uma maneira padrão de assinar e reutilizar t Aqui, vimos essa metodologia usada para resgatar os fundos multisig. No futuro, também podemos usá-la para resgatar os fundos que foram trancados com outros scripts P2SH mais complexos, conforme explicado no Capítulo 9. -## Resumo: Gastando uma Transação Multsig +## Resumo: Gastando uma Transação com Multisig Acontece que gastar dinheiro enviado para um endereço multisig pode dar um pouco de trabalho. Mas, contanto que tenhamos os endereços originais e nosso redemScript, podemos fazer isso assinando uma transação bruta com cada endereço diferente e fornecendo mais algumas informações ao longo do caminho. ## O Que Vem Depois? -Vamos continuar "Expandindo as transações de Bitcoin com multisigs" na seção [§6.3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada](06_3_Sending_an_Automated_Multisig.md). \ No newline at end of file +Vamos continuar "Expandindo Transações no Bitcoin com Multisigs" na seção [§6.3: Enviando & Gastando um Multisig Automatizado](06_3_Sending_an_Automated_Multisig.md). \ No newline at end of file From a75034324ca297fd10d6d6105e2ede86fd52e9df Mon Sep 17 00:00:00 2001 From: namcios Date: Mon, 19 Jul 2021 16:32:10 -0300 Subject: [PATCH 50/50] Review 06_3 --- pt/06_3_Sending_an_Automated_Multisig.md | 36 ++++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pt/06_3_Sending_an_Automated_Multisig.md b/pt/06_3_Sending_an_Automated_Multisig.md index 20136c6..f07ba8c 100644 --- a/pt/06_3_Sending_an_Automated_Multisig.md +++ b/pt/06_3_Sending_an_Automated_Multisig.md @@ -1,14 +1,14 @@ -# 6.3: Enviando e Gastando uma Transação Multisig de Maneira Automatizada +# 6.3: Enviando & Gastando um Multisig Automatizado -A técnica padrão para criar endereços com várias assinaturas e gastar os fundos é complexa, mas é um exercício interessante para entender um pouco mais como funcionam e como podemos manipulá-los em um nível relativamente baixo. No entanto, o Bitcoin Core tornou os multisigs mais fáceis de serem manipulados nas novas versões. +A técnica padrão para criar endereços multi-assinatura e gastar os fundos é complexa, mas é um exercício interessante para entender um pouco mais como funcionam e como podemos manipulá-los em um nível relativamente baixo. No entanto, o Bitcoin Core tornou os multisigs mais fáceis de serem manipulados nas novas versões. > :warning: **AVISO DE VERSÃO:** O comando ```addmultisigaddress``` está disponível no Bitcoin Core v0.10 ou superior. -## Criando um endereço Multisig em nossa carteira +## Criando um Endereço Multisig em Nossa Carteira Para tornar os fundos enviados para endereços multisig mais fáceis de serem gastos, só precisamos fazer algumas pré-configurações usando o comando ```addmultisigaddress```. Não é o que gostaríamos de fazer se estivéssemos escrevendo programas de carteiras que utilizam multisig, mas se estivesse apenas tentando receber alguns fundos, isso poderia evitar alguns problemas. -### Coletando as chaves +### Coletando as Chaves Vamos começar criando os endereços P2PKH e recuperando as chaves públicas, como de costume, para cada usuário que fará parte do multisig: ``` @@ -25,9 +25,9 @@ machine2$ bitcoin-cli -named getaddressinfo address=$address4 | jq -r '. | .pubk 02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f ``` -### Criando o endereço Multisig em qualquer lugar +### Criando o Endereço Multisig em Todos os Lugares -Em seguida, vamos criar o multisig em _cada máquina que contribuiu com as assinaturas_ usando um novo comando, ```addmultisigaddress```, ao invés de ```createmultisig```. Este novo comando salva algumas das informações da nossa carteira, tornando muito mais fácil gastar o dinheiro no futuro. +Em seguida, vamos criar o multisig em _cada máquina que contribuiu com assinaturas_ usando um novo comando, ```addmultisigaddress```, ao invés de ```createmultisig```. Este novo comando salva algumas das informações na nossa carteira, tornando muito mais fácil gastar o dinheiro no futuro. ``` machine1$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["'$address3'","02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f"]''' { @@ -43,9 +43,9 @@ machine2$ bitcoin-cli -named addmultisigaddress nrequired=2 keys='''["0297e681bf "descriptor": "wsh(multi(2,[ae42a66f]0297e681bff16cd4600138449e2527db4b2f83955c691a1b84254ecffddb9bfbfc,[fe6f2292/0'/0'/2']02a0d96e16458ff0c90db4826f86408f2cfa0e960514c0db547ff152d3e567738f))#cc96c5n6" } ``` -Conforme observado na seção anterior, atualmente não importa se usamos endereços ou chaves públicas, então mostramos o outro mecanismo aqui, misturando os dois. Iremos obter o mesmo endereço multisig de qualquer maneira. No entanto, _devemos usar a mesma ordem sempre_. Portanto, é melhor que os membros do multisig verifiquem entre si a ordem dos dados para ter certeza de que todos obtiveram o mesmo resultado. +Conforme observado na seção anterior, atualmente não importa se usamos endereços ou chaves públicas, então temos mostrado o outro mecanismo aqui, misturando os dois. Iremos obter o mesmo endereço multisig de qualquer maneira. No entanto, _devemos usar a mesma ordem sempre_. Portanto, é melhor que os membros do multisig verifiquem entre si a ordem dos dados para ter certeza de que todos obtiveram o mesmo resultado. -### Esperando para receber os fundos +### Atente-se aos Fundos Depois disso, os membros do multisig ainda precisarão executar o comando ```importaddress``` para observar os fundos recebidos no endereço multisig: ``` @@ -54,9 +54,9 @@ machine1$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAo machine2$ bitcoin-cli -named importaddress address=2Mzw7WBvh9RAQ4ssKqxyNyP7L9NAojLqSW8 rescan="false" ``` -## Gastando novamente com uma transação automatizada +## Gastando Novamente com uma Transação Automatizada -Posteriormente, podemos receber os fundos no endereço com várias assinaturas sem nenhum problema. O uso do ```addmultisigaddress``` é simplesmente uma questão burocrática por parte dos destinatários: Um pouco de contabilidade para facilitar a vida deles quando desejarem gastar os saldos. +Posteriormente, poderemos receber os fundos no endereço multisig normalmente. O uso do ```addmultisigaddress``` é simplesmente uma questão burocrática por parte dos destinatários: um pouco de contabilidade para facilitar a vida deles quando desejarem gastar os saldos. Mas, isso torna a vida muito mais fácil. Como as informações foram salvas na carteira, os assinantes poderão gastar os fundos enviados para o endereço com várias assinaturas exatamente como qualquer outro endereço, ao invés de assinar sempre em várias máquinas diferentes. @@ -68,11 +68,11 @@ machine1$ utxo_txid=b9f3c4756ef8159d6a66414a4317f865882ee04beb57a0f8349dafcc98f5 machine1$ utxo_vout=0 machine1$ recipient=$(bitcoin-cli getrawchangeaddress) ``` -Vamos criar uma transação bruta: +Criamos uma transação bruta: ``` machine1$ rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "'$recipient'": 0.00005}''') ``` -E depois, assiná-la: +E depois, a assinamos: ``` machine1$ bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex { @@ -96,25 +96,25 @@ machine1$ bitcoin-cli -named signrawtransactionwithwallet hexstring=$rawtxhex } ``` -Observe que não precisamos mais da ajuda extra do comando ```signrawtransactionwithkey```, porque todas essas informações já estão em nossa carteira. Mais importante, não tornamos nossas chaves privadas vulneráveis ​​ao manipulá-las diretamente. Ao invés disso, o processo é _exatamente_ o mesmo que gastar um UTXO normal, exceto que a transação não foi totalmente assinada no final. +Observe que não precisamos mais dar ajuda extra ao comando ```signrawtransactionwithkey```, porque todas as informações extras já estavam em nossa carteira. Mais importante, não tornamos nossas chaves privadas vulneráveis ​​ao manipulá-las diretamente. Ao invés disso, o processo é _exatamente_ o mesmo que gastar um UTXO normal, exceto que a transação não foi totalmente assinada no final. -### Assinando em outras máquinas +### Assinando em Outras Máquinas A etapa final é exportar o ```hex``` parcialmente assinado para a outra máquina e assinar a transação novamente: ``` machine2$ signedtx=$(bitcoin-cli -named signrawtransactionwithwallet hexstring=02000000014ecda61c45f488e35c613a7c4ae26335a8d7bfd0a942f026d0fb1050e744a67d000000009100473044022025decef887fe2e3eb1c4b3edaa155e5755102d1570716f1467bb0b518b777ddf022017e97f8853af8acab4853ccf502213b7ff4cc3bd9502941369905371545de28d0147522102e7356952f4bb1daf475c04b95a2f7e0d9a12cf5b5c48a25b2303783d91849ba421030186d2b55de166389aefe209f508ce1fbd79966d9ac417adef74b7c1b5e0777652aeffffffff0130e1be07000000001976a9148dfbf103e48df7d1993448aa387dc31a2ebd522d88ac00000000 | jq -r '.hex') ``` -Quando todos os os assinantes confirmaram a assinatura, estaremos prontos para enviar a transação para a rede: +Quando todos os assinantes confirmaram a assinatura, estaremos prontos para enviar a transação para a rede: ``` machine2$ bitcoin-cli -named sendrawtransaction hexstring=$signedtx 3ce88839ac6165aeadcfb188c490e1b850468eff571b4ca78fac64342751510d ``` Tal como acontece com o atalho discutido na seção [§4.5: Enviando Moedas com Transações Brutas Automatizadas](04_5_Sending_Coins_with_Automated_Raw_Transactions.md), o resultado é muito mais fácil, mas perdemos certo controle no processo. -## Resumo: Enviando e Gastando uma Transação Multisig de Maneira Automatizada +## Resumo: Enviando & Gastando um Multisig Automatizado -Existe uma maneira mais fácil de gastar fundos enviados para os nossos endereços multisig que simplesmente requerem o uso do comando ```addmultisigaddress``` quando criamos nosso endereço. Ele não demonstra os meandros do gasto do P2SH e não nos dará um controle abrangente, mas se queremos apenas receber nossas moedas, este pode ser o melhor caminho. +Existe uma maneira mais fácil de gastar fundos enviados para os nossos endereços multisig que simplesmente requerem o uso do comando ```addmultisigaddress``` quando criamos nosso endereço. Ele não demonstra as complexidades do gasto do P2SH e não nos dará um controle abrangente, mas se queremos apenas receber nossas moedas, este pode ser o melhor caminho. ## O Que Vem Depois? -Saiba mais sobre "Expandindo as transações de Bitcoin com multisigs" no [Capítulo 7: Expandindo as transações do Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). \ No newline at end of file +Saiba mais sobre "Expandindo Transações no Bitcoin com Multisigs" no [Capítulo 7: Expandindo Transações no Bitcoin com PSBTs](07_0_Expanding_Bitcoin_Transactions_PSBTs.md). \ No newline at end of file