Bitcoin/Tworzenie transakcji

Wstęp edytuj

Dla kogo „zaawansowane tworzenie transakcji” (operowanie na surowych transakcjach)?

  • Pomoc w zrozumieniu mechanizmów waluty, eksperymentowanie z możliwościami
  • Tworzenie własnego oprogramowania i nakładek do wysyłania monet lub chęć stworzenia osobnej waluty z rozszerzonym mechanizmem transakcji
  • Precyzyjna kontrola nad wydawanymi wejściami
  • Wysyłanie do odbiorców nie identyfikowanych adresami
  • Korzystanie z adresów wielosygnaturowych, czego nie umożliwia oficjalne GUI
  • Wykorzystywanie innych funkcjonalności w mechanizmie transakcji, np. opóźnione zatwierdzanie

Uwagi:

  • Podczas ręcznego dobierania wejść i wyjść upewnij się, że ich sumy są podobne. Suma wyjść powinna być tylko nieznacznie mniejsza niż wartości wejść, różnica zostanie uznana za opłatę transakcyjną! Pamiętaj więc o przesłaniu reszty monet na swój adres (jako jedno z wyjść). Pozwoli to uniknąć utraty dużej ilości środków. Klienty sieci starają się zapobiec takim sytuacjom, ale należy uważać.
  • Testy, ćwiczenia należy wykonywać w sieci testowej (testnet lub regtest). Nie spowoduje to marnowania wartościowych środków oraz zapychania głównej sieci. Więcej informacji.

Wykorzystanie portfela edytuj

Opis zautomatyzowanego wysyłania transakcji (oraz odbierania) znajduje się w rozdziale przyjmowanie płatności. Opisywane tam sposoby nie wymagają operowania na surowych transakcjach, ponieważ istnieją zarówno komendy wykonujące proste czynności i wykonujące całe procesy w sposób zautomatyzowany, jak i dedykowane dla manipulowania strukturą surowej transakcji.

Techniczna struktura transakcji edytuj

Poniżej przestawiona jest w formie JSON zawartość transakcji. Taki sposób przedstawienia generuje polecenie getrawtransaction. Niektóre z widocznych właściwości nie są częścią przesyłanych właściwych danych transakcji, ale klient sieci przedstawia je, aby analizujący uzyskał jak najwięcej informacji o transakcji. W rzeczywistości transakcje nie są przesyłane w JSON, a jako ciągi bitów, gdzie każde pole ma określoną długość i miejsce w kolejności.

{
	"hex" : "",
	"txid" : "",
	"version" : 1,
	"locktime" : 0,
	"vin" : [
		{
		"txid" : "",
		"vout" : 0,
		"scriptSig" : {
			"asm" : "(...)",
			"hex" : "(...)"
		},
		"sequence" : 4294967295
		}
	],

	"vout" : [
		{
		"value" : 50.00000000,
		"n" : 0,
		"scriptPubKey" : {
			"asm" : "OP_DUP OP_HASH160 (...) OP_EQUALVERIFY OP_CHECKSIG",
			"hex" : "(...)",
			"reqSigs" : 1,
			"type" : "pubkeyhash",
				"addresses" : [
					"(...)"
				]
			}
		}
	]
}
  • hex – informacje zawarte w transakcji zapisane szesnastkowo
  • txid – hash danych transakcji, jest też jednocześnie jej identyfikatorem
  • version – wersja struktury transakcji. Na razie tylko jedna jest możliwa
  • locktime – czas lub blok, który musi minąć, aby zatwierdzić transakcję (opóźnione zatwierdzanie)
  • vin – tablica zawierająca wejścia transakcji. Każdy element tablicy zawiera następujące właściwości:
    • txid – identyfikator (hash) transakcji wejściowej
    • vout – numer wyjścia powyżej wspomnianej transakcji
    • scriptSig – skrypt będący podpisem pasującym do skryptu podanego w wyjściu tego wejścia
      • asm – zapis opcodów w formie czytelnej
      • hex – zapis szesnastkowy poleceń
    • sequence – numer aktualizacji w opóźnionym zatwierdzaniu
  • vout – tablica zawierająca wyjścia transakcji. Każdy element tablicy zawiera następujące właściwości:
    • value
    • n
    • scriptPubKey
      • asm – zapis opcodów (poleceń skryptu) w formie czytelnej
      • hex – zapis szesnastkowy poleceń
      • reqSigs – wymagana liczba podpisów

Dodatkowe opisy:

Wersja transakcji
Numer wersji transakcji opisuje, która wersja standardu transakcji została zastosowana. W przypadku późniejszych modyfikacji protokołu pod tym kątem tj. jeżeli zostaną dodane nowe rodzaje informacji jakie ma zawierać transakcja, numer zwiększy się. Dzięki temu klient sieci będzie wiedział, czy transakcja z dodatkowymi polami jest prawidłowa czy nie. Bloki również mają podział na wersje. Według stanu na 2016 rok istnieje jedna wersja formatu transakcji i 3 wersje właściwości bloków.
Locktime
Zobacz więcej.

Manipulowanie strukturą edytuj

Ręczne sklejanie takiej struktury może być niewygodne. Można taką generować na dwa sposoby (a nawet i więcej, opisane tutaj są dostępne w Bitcoin Core) i nadal mieć możliwość ingerencji w każdą właściwość.

Te sposoby to:

  • Wykorzystanie poleceń RPC demona klienta sieci. Dostępne są też polecenia dalej ją przetwarzające, np. podpisywanie czy rozgłaszanie,
  • Skorzystanie z dołączonego programu bitcoin-tx, który generuje transakcje w formie JSON lub HEX z podanymi danymi.

Bitcoin-tx edytuj

Bitcoin-tx to program dołączany wraz z Bitcoin Core (także generowany podczas kompilacji) do tworzenia struktury transakcji w JSON lub HEX, aby potem móc dalej ją przetwarzać w kliencie sieci.

Składnia to:

./bitcoin-tx [opcje] [TX_HEX lub -create] [komendy]

(zamiast TX_HEX wpisz zakodowaną szesnastkowo transakcję, którą chcesz zmodyfikować lub -create, aby utworzyć od podstaw)

Każdą z opcji poprzedza się myślnikiem, a oddziela spacjami. Opcje to:

  • ? – pomoc, opis parametrów. Samo wywołanie ./bitcoin-tx bez parametrów da taki sam efekt,
  • json – wyświetlaj wynik w JSON zamiast HEX,
  • txid – wyświetl sam identyfikator transakcji (hash),
  • testnet – operuj na transakcjach w sieci testowej,
  • regtest – operuj na transakcjach w sieci testowej regtest.

Komendy służą do modyfikacji pól transakcji. Można wywołać kilka komend jednocześnie, nawet o takich samych nazwach. Oddzielać spacją, nie poprzedzać myślnikiem.

  • in=TXID:VOUT – dodaj wejście #VOUT z transakcji o hashu TXID
  • delin=N – usuń wejście o numerze N z modyfikowanej transakcji
  • delout=N – usuń wyjście o numerze N z modyfikowanej transakcji
  • outaddr=WARTOŚĆ:ADRES – dodaj wyjście do transakcji. Wysyłanie na adres
  • outscript=WARTOŚĆ:SKRYPT – dodaj wyjście do transakcji. Niestandardowy skrypt
  • locktime=Nmoment zatwierdzenia w opóźnionym zatwierdzaniu. Domyślnie 0
  • nversion=N – ustaw wersję formatu transakcji. Domyślnie 1

Przykład edytuj

W tym przykładzie operujemy na sieci testowej regtest. Adresy mają inny znak na początku, a żeby wysłać taką transakcję, należy uruchomić klienta sieci z opcją -regtest. Można tam przeprowadzać dowolne testy bez utraty „prawdziwych” środków. Można też użyć -testnet, ale jest to publiczny łańcuch i ostre testowanie jest utrudnione.

Wydaj wyjście 0 z transakcji 5e72b5c205d6331f83a20893e42739e640aec0d76def943131f26ff99d0bb09b (jest na nim 4 BTC) i wyślij:

  • Na adres mjEC22Z3GdTadmLwvCgkdBFKdn2EQ2PuFh 2 BTC
  • Na adres n49UhEaKfJZv9qQrkR3Hn13zdFWAKAhfyN 1,9 BTC

W tym przypadku opłatą transakcyjną, która jest różnicą między sumą wejść a sumą wyjść, wyniesie 0,1 BTC.

./bitcoin-tx.exe -json -create -regtest in=5e72b5c205d6331f83a20893e42739e640aec0d76def943131f26ff99d0bb09b:0 outaddr=2:mjEC22Z3GdTadmLwvCgkdBFKdn2EQ2PuFh outaddr=1.9:n49UhEaKfJZv9qQrkR3Hn13zdFWAKAhfyN

Po zakończeniu transakcję należy podpisać i rozesłać do sieci.

Podpisać można dwoma drogami:

  • Nadal za pomocą tego narzędzia,
  • W kliencie Bitcoin Core (wtedy wymagane klucze prywatne mogą zostać pobrane z portfela, jeżeli w nim są).

Za pomocą Bitcoin Core:

  1. Aby podpisać transakcję, potrzebujemy ją zakodować w HEX. Z powyższej przykładowej komendy usuń opcję -json i wywołaj jeszcze raz.
  2. Skopiuj wynikowy ciąg znaków.
  3. Wywołaj polecenie RPC signrawtransaction HEX – zamiast HEX wklej wcześniej skopiowany ciąg.
  4. Otrzymasz nową zakodowaną transakcję. Znajduje się ona w polu hex. Zwróć uwagę, czy wartość complete to true. Skopiuj ją (zawartość cudzysłowu). Podejrzeć JSON podpisanej transakcji możesz wywołując polecenie decoderawtransaction NOWY_HEX.
  5. Wykonaj polecenie sendrawtransaction NOWY_HEX, aby rozgłosić transakcję w sieci. Jako wynik otrzymasz hash wysłanej transakcji lub informację o błędzie.

Tworzenie komendami RPC edytuj

Niewykorzystane wyjścia edytuj

Pobieranie listy niewykorzystanych wyjść transakcji znajdujących się w portfelu – listunspent z opcjonalnymi parametrami:

  1. Minimalna liczba potwierdzeń
  2. Maksymalna liczba potwierdzeń
  3. Tylko odebranych przez wskazane adresy (tablica JSON – [adres1, adres2])

Wynik:

[
{
"txid" : "id transakcji",
"vout" : n,
"address" : "adres",
"account" : "konto do którego przypisano adres",
"scriptPubKey" : "the script key",
"amount" : x.xxx,
"confirmations" : n
}
,...
]

Tworzenie transakcji edytuj

createrawtransaction [{"txid":"hash_wejściowej","vout":numer_wyjścia_wejściowej},...] {"adres": kwota, ...}

Podpisywanie edytuj

signrawtransaction "hexstring" ( [{"txid":"id","vout":n,"scriptPubKey":"hex","redeemScript":"hex"},...] ["privatekey1",...] sighashtype )
  1. Surowa transakcja zakodowana szesnastkowo (jedyny obowiązkowy parametr)
  2. Tablica wejść (do dalszej modyfikacji, nie podawać jeżeli stworzyłeś już transakcję, która ma oczekiwane wejścia)
  3. Tablica JSON kluczy prywatnych, każdy zakodowany w base58. Domyślnie, nie podane tutaj szukane są w portfelu.
  4. Rodzaj hashowania podpisu:
    • ALL – podpisuje wszystkie wejścia i wyjścia
    • NONE – podpisuje tylko wejścia. Wyjścia nie sa podpisywane, więc można je modyfikować przed całkowitym podpisaniem.
    • SINGLE – podpisuje wybrane wejście i jedno wyjście z takim samym numerem kolejności.
    • ANYONECANPAY w kombinacji z jednym z powyższych trzech, np. SINGLE|ANYONECANPAY. Pozwala na modyfikację wejść i wyjść (dla ALL – pozwala na dopisywanie się tylko do wejść, NONE – podpisz tylko dane wejście, a resztę można zmieniać, SINGLE – podpisz parę wejście-wyjście, ale resztę można zmieniać).

Inne edytuj

  • decoderawtransaction "HEX" – ukazuje transakcję w formie czytelnej (JSON)
  • decodescript "HEX" – podaje opcody po podaniu zakodowanego szesnastkowo skryptu
  • sendrawtransaction "hex podpisanej transakcji" (allowhighfees) – rozgłasza podpisaną transakcję w sieci. Drugi parametr (bool, nieobowiązkowy) pozwala na wysłanie transakcji mimo podejrzanie wysokiej opłaty transakcyjnej (zaleca się tylko w sieciach testowych i jeżeli wiesz co robisz).

Adresy wielosygnaturowe edytuj

Tworzenie transakcji wielosygnaturowych. Tworzenie adresów wielosygnaturowych, wysyłanie na takowe, oraz wydawanie środków z takich adresów.

Adresy wielosygnaturowe (multisig) to adresy, z których aby wysłać monety, należy podpisać wydawanie za pomocą większej niż 1 kluczy prywatnych lub też jednym kluczem spośród kilku składających się na adres.

Tworzenie adresu edytuj

addmultisigaddress nrequired ["klucz1",...] ("konto")
  1. nrequired (liczba, wymagane) – liczba wymaganych podpisów, czyli minimum ile z pośród podanych kluczy musi podpisać transakcje by były ważne.
  2. Tablica JSON kluczy. Mogą to być adresy lub zakodowane szesnastkowo klucze publiczne. Wymagane.
  3. Konto (string, nieobowiązkowe) – konto portfela, do którego przydzielić wygenerowany adres.

Otrzymamy obiekt JSON składający się z nowego adresu multisig, na który można przesyłać Bitcoiny oraz redeemScript, który będzie potrzebny do wysyłania otrzymanych na ten adres monet.

Wysyłanie na adres wielosygnaturowy edytuj

Na adres wielosygnaturowy można normalnie wysłać za pomocą interfejsu GUI lub powyżej opisanych metod.

Skrypt wydawania ma taką postać: OP_HASH160 CIĄG_ZNAKÓW OP_EQUAL. Taka transakcja określana jest płatnością P2SH.

Wydawanie z adresu wielosygnaturowego edytuj

Tworzymy surową transakcję za pomocą opisanych wcześniej sposobów, z odwołaniem się do transakcji przychodzącej na adres multisig i określamy adresatów.

Następnie musi zostać podpisana przez klucze prywatne, które składają się na adres multisig. Transakcja zostanie uznana za podpisaną, jeżeli zostanie podpisana przynajmniej tyloma kluczami, ile określono jako minimum przy tworzeniu takiego adresu.

signrawtransaction 1 [{"txid": "2", "vout": 3, "scriptPubKey": "4", "redeemScript": "5"}] ["6"]

Gdzie za parametry ponumerowane 1–5 podstaw:

  1. Surową (hex) transakcję, lub podpisaną wcześniej przez część kluczy
  2. Transakcję wejściową
  3. Numer wyjścia transakcji wyjściowej, które wydajesz
  4. Zawartość pola „hex” wydawanego wyjścia
  5. redeemScript pozyskany przy tworzeniu adresu multisig
  6. Klucz prywatny lub kilka kluczy. Nie podane szuka w portfelu.

Można podpisać transakcję wszystkimi wymaganymi kluczami lub etapami (zwłaszcza, gdy podpisują różne osoby).

Otrzymamy zakodowaną transakcję podpisaną podanymi kluczami. Jeżeli wydatkowanie ma wystarczającą wymaganą liczbę podpisów, w odpowiedzi pole „completed” będzie „true”. Jeżeli wciąż brakuje podpisów lub będą problemy, będzie to „false”.

Aby podpisać transakcję kolejnymi kluczami, skopiuj zawartość pola „hex” odpowiedzi tej funkcji (transakcja podpisana przez część kluczy) i wklej do następnego wywołania signrawtransaction podpisującego kolejnymi kluczami.

Po zebraniu wystarczającej liczby podpisów, roześlij transakcję do sieci.

Opóźnione zatwierdzanie edytuj

Istnieje możliwość, aby określić, minimalnie w którym bloku transakcja może być zatwierdzona. Czyli nie wcześniej niż w X bloku (lub nie wcześniej niż podany czas), ale też nie ma możliwości przyspieszenia zatwierdzania tym sposobem.

Celem tego może być możliwość wycofania przez wysyłających transakcji, zanim zostanie ona zatwierdzona. W takim przypadku należy wysłać inną transakcję wydającej wejścia, które miały ustawione odpowiedzialne za to parametry, ale tym razem ze standardowymi.

Za włączenie tej funkcji odpowiadają właściwości wejścia transakcji:

  • locktime – czas uniksowy (jeżeli powyżej 500 milionów) lub minimalny numer bloku, przed którymi nie zatwierdzać transakcji. Uwaga: w przypadku podania czasu, transakcja może być zatwierdzona już 2 godziny przed podanym czasem. Czas należy podać absolutny, tj. nie liczba sekund za ile zatwierdzić tylko ile powinno minąć od ery Uniksa do minimalnego momentu włączenia do bloku.
  • sequence – jeżeli wartość to maksymalna liczba, jaką można umieścić w typie danych int to wyłącza tę funkcję. Aby włączyć, należy podać dowolną inną liczbę. Miało służyć do ustalania kolejności zmian w podpisywaniu transakcji.

Narzędzia on-line edytuj

  • Brain wallet – tworzenie adresów z łatwych do zapamiętania zdań, tworzenie i wysyłanie transakcji z wskazaniem wejść.
  • Rozgłaszanie – transakcje można też wysłać poprzez niektóre strony internetowe, np. eksploratory bloków i niektóre serwisy oferujące portfele on-line.

Zobacz też edytuj