TON-Testclient (Telegram Open Network) und die neue Fift-Sprache für intelligente Verträge

Vor mehr als einem Jahr wurde bekannt, dass der Telegram Messenger plant, sein eigenes dezentrales Netzwerk Telegram Open Network freizugeben. Dann wurde ein umfangreiches technisches Dokument verfügbar, das vermutlich von Nikolai Durov verfasst wurde und die Struktur des zukünftigen Netzwerks beschrieb. Für diejenigen, die es verpasst haben, empfehle ich, dass Sie meine Nacherzählung dieses Dokuments lesen ( Teil 1 , Teil 2 ; der dritte Teil verstaubt leider immer noch in Entwurfskopien).


Seitdem gab es keine wesentlichen Neuigkeiten über den Entwicklungsstatus von TON, bis vor ein paar Tagen (in einem der inoffiziellen Kanäle ) ein Link zur Seite https://test.ton.org/download.html erschien , wo:


ton-test-liteclient-full.tar.xz - leichter Client-Quellcode für das TON-Testnetzwerk;
ton-lite-client-test1.config.json - Konfigurationsdatei für die Verbindung mit einem Testnetzwerk;
README - Informationen zum Erstellen und Starten des Clients;
HOWTO - Schritt-für-Schritt-Anleitung zum Erstellen eines intelligenten Vertrags mit einem Kunden;
ton.pdf - aktualisiertes Dokument (vom 2. März 2019) mit einem technischen Überblick über das TON-Netzwerk;
tvm.pdf - technische Beschreibung von TVM (TON Virtual Machine, TON Virtual Machine);
tblkch.pdf - technische Beschreibung der TON-Blockchain;
fiftbase.pdf - eine Beschreibung der neuen Fift-Sprache, mit der intelligente Verträge in TON erstellt werden sollen.


Ich wiederhole, es gab keine offizielle Bestätigung der Seite und all dieser Dokumente durch das Telegramm, aber das Volumen dieser Materialien macht sie durchaus plausibel. Führen Sie einen veröffentlichten Client auf eigenes Risiko aus .


Testen Sie den Client-Build


Versuchen wir zunächst, einen Testclient zu erstellen und auszuführen. Glücklicherweise beschreibt README diesen einfachen Prozess ausführlich. Ich werde dies am Beispiel von macOS 10.14.5 tun, ich kann nicht für den Erfolg der Montage auf anderen Systemen bürgen.


  1. Laden Sie das Archiv herunter und entpacken Sie es mit Quellcodes . Es ist wichtig, die neueste Version herunterzuladen, da die Abwärtskompatibilität derzeit nicht garantiert ist.


  2. Wir stellen sicher, dass die neuesten Versionen von make, cmake (Version 3.0.2 oder höher), OpenSSL (einschließlich C-Header-Dateien), g ++ oder clang auf dem System installiert sind. Ich musste nichts neu installieren, alles wurde sofort gesammelt.


  3. Angenommen, die Quellen werden in den Ordner ~/lite-client entpackt. Separat erstellen wir einen leeren Ordner für das zusammengestellte Projekt (z. B. ~/liteclient-build ) und cd ~/liteclient-build daraus ( cd ~/liteclient-build ) cd ~/liteclient-build Befehle auf:


     cmake ~/lite-client cmake --build . --target test-lite-client 

    Erfolgreicher Kundenaufbau

    Um den Fift-Sprachinterpreter für intelligente Verträge zu erstellen (siehe unten), rufen wir auch an


     cmake --build . --target fift 

  4. Laden Sie die aktuelle Konfigurationsdatei herunter, um eine Verbindung zum Testnetzwerk herzustellen, und legen Sie sie im Ordner mit dem zusammengestellten Client ab.


  5. Fertig , Sie können den Client starten:


     ./test-lite-client -C ton-lite-client-test1.config.json 


Wenn alles richtig gemacht ist, sollten Sie so etwas sehen:


Client-Start


Wie Sie sehen können, stehen nur wenige Befehle zur Verfügung:


help - Zeigt diese Befehlsliste an.
quit - quit ;
time - Zeigt die aktuelle Zeit auf dem Server an.
status - Zeigt den Status der Verbindung und der lokalen Datenbank an.
last - Aktualisiert den Status der Blockchain (lädt den letzten Block). Es ist wichtig, diesen Befehl vor allen Anforderungen auszuführen, um sicherzustellen, dass Sie genau den aktuellen Status des Netzwerks sehen.
sendfile <filename> - Laden sendfile eine lokale Datei in das TON-Netzwerk sendfile . Dies ist die Interaktion mit dem Netzwerk - einschließlich beispielsweise der Erstellung neuer intelligenter Verträge und der Anforderung, Geld zwischen Konten zu überweisen.
getaccount <address> - getaccount den aktuellen getaccount (zum Zeitpunkt der Ausführung des last Befehls) mit der angegebenen Adresse an.
privkey <filename> - lädt den privaten Schlüssel aus der lokalen Datei.


Wenn Sie beim Client-Start den Ordner mit der Option -D ihn übergeben, wird der letzte Block der Master-Kette hinzugefügt:


 ./test-lite-client -C ton-lite-client-test1.config.json -D ~/ton-db-dir 

Jetzt können wir zu interessanteren Dingen übergehen - die Sprache Fift lernen, versuchen, einen intelligenten Vertrag zu erstellen (z. B. eine Testmappe erstellen), ihn in das Netzwerk hochladen und versuchen, Geld zwischen Konten zu überweisen.


Fünfzig Sprache


In fiftbase.pdf können Sie herausfinden, dass das Telegrammteam zur Erstellung intelligenter Verträge eine neue Stapelsprache Fift erstellt hat (anscheinend ab der fünften Ziffer in Analogie zu Forth - einer Sprache, mit der Fift viel gemeinsam hat).


Das Dokument ist mit 87 Seiten ziemlich umfangreich, und ich werde seinen Inhalt im Rahmen dieses Artikels nicht im Detail nacherzählen (zumindest, weil ich es selbst nicht zu Ende gelesen habe :). Ich werde auf die Hauptpunkte eingehen und einige Codebeispiele in dieser Sprache geben.


Grundsätzlich ist die Syntax von Fift recht einfach: Der Code besteht aus Wörtern , die normalerweise durch Leerzeichen oder Zeilenumbrüche getrennt sind (Sonderfall: Einige Wörter benötigen kein Trennzeichen nach sich selbst). Jedes Wort ist eine Zeichenfolge, bei der zwischen Groß- und Kleinschreibung unterschieden wird und die einer Definition entspricht (grob gesagt, was der Interpreter tun muss, wenn er auf dieses Wort stößt). Wenn das Wort nicht definiert ist, versucht der Interpreter, es als Zahl zu analysieren und auf den Stapel zu legen. Übrigens sind die Zahlen hier - plötzlich - 257-Bit-Ganzzahlen, aber es gibt überhaupt keine Bruchzahlen - genauer gesagt, sie werden sofort zu einem Paar von Ganzzahlen, die den Zähler und Nenner eines rationalen Bruchs bilden.


Wörter interagieren normalerweise mit Bedeutungen am oberen Rand des Stapels. Ein separater Worttyp - Präfix - verwendet nicht den Stapel, sondern die nachfolgenden Zeichen aus der Quelldatei. Beispielsweise werden Zeichenfolgenliterale auf diese Weise implementiert. Das Zeichen "Anführungszeichen" ( " ) ist ein Präfixwort, das nach dem nächsten (schließenden) Anführungszeichen sucht und die Zeichenfolge zwischen ihnen auf den Stapel legt. Einzeilig ( // ) und mehrzeilig ( /* ) verhalten sich gleich. Kommentare.


Damit endet fast die gesamte interne Struktur der Sprache. Alles andere (einschließlich Kontrollstrukturen) wird als Wörter definiert (entweder intern, wie z. B. arithmetische Operationen und die Definition neuer Wörter, oder in der "Standardbibliothek" Fift.fif , die sich im crypto/fift in der Quelle befindet).


Ein einfaches Beispiel für ein Fift-Programm:


 { dup =: x dup * =: y } : setxy 3 setxy x . y . xy + . 7 setxy x . y . xy + . 

Die erste Zeile definiert das neue Wort setxy (beachten Sie das Präfix { , das den Block vor dem Schließen erstellt } und das Präfix : das das Wort tatsächlich definiert). setxy nimmt eine Zahl vom oberen setxy des Stapels, definiert sie (oder definiert sie neu) als globale Konstante x und das Quadrat dieser Zahl als Konstante y (da die Werte der Konstanten neu definiert werden können, würde ich sie lieber Variablen nennen, aber ich folge der Benennung in der Sprache).


In den nächsten beiden Zeilen wird eine Zahl auf den Stapel gelegt, setxy wird setxy , dann werden die Werte der Konstanten x , y ausgegeben (das Wort wird für die Ausgabe verwendet). Beide Konstanten werden auf den Stapel gelegt, summiert und das Ergebnis wird ebenfalls angezeigt. Als Ergebnis werden wir sehen:


 3 9 12 ok 7 49 56 ok 

(Der Interpreter druckt die Zeile "OK", wenn die Verarbeitung der aktuellen Zeile im interaktiven Eingabemodus abgeschlossen ist.)


Nun, ein vollständiges Codebeispiel:


 "Asm.fif" include -1 constant wc // create a wallet in workchain -1 (masterchain) // Create new simple wallet <{ SETCP0 DUP IFNOTRET INC 32 THROWIF // return if recv_internal, fail unless recv_external 512 INT LDSLICEX DUP 32 PLDU // sign cs cnt c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk s1 s2 XCPU // sign cs cnt pubk cnt' cnt EQUAL 33 THROWIFNOT // ( seqno mismatch? ) s2 PUSH HASHSU // sign cs cnt pubk hash s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk CHKSIGNU // pubk cs cnt ? 34 THROWIFNOT // signature mismatch ACCEPT SWAP 32 LDU NIP DUP SREFS IF:<{ 8 LDU LDREF // pubk cnt mode msg cs s0 s2 XCHG SENDRAWMSG // pubk cnt cs ; ( message sent ) }> ENDS INC NEWC 32 STU 256 STU ENDC c4 POPCTR }>c // code <b 0 32 u, newkeypair swap dup constant wallet_pk "new-wallet.pk" B>file B, b> // data // no libraries <bb{00110} s, rot ref, swap ref, b> // create StateInit dup ."StateInit: " <s csr. cr dup hash dup constant wallet_addr ."new wallet address = " wc . .": " dup x. cr wc over 7 smca>$ type cr 256 u>B "new-wallet.addr" B>file <b 0 32 u, b> dup ."signing message: " <s csr. cr dup hash wallet_pk ed25519_sign_uint rot <bb{1000100} s, wc 8 i, wallet_addr 256 u, b{000010} s, swap <ss, b{0} s, swap B, swap <ss, b> dup ."External message for initialization is " <s csr. cr 2 boc+>B dup Bx. cr "new-wallet-query.boc" tuck B>file ."(Saved to file " type .")" cr 

Diese beängstigend aussehende Datei wurde entwickelt, um einen intelligenten Vertrag zu erstellen. Sie wird nach der Ausführung in der new-wallet-query.boc . Bitte beachten Sie, dass hier eine andere Assembler-Sprache für die TON Virtual Machine verwendet wird (ich werde nicht näher darauf eingehen), deren Anweisungen in die Blockchain eingefügt werden.


Daher ist der Assembler für TVM in Fift geschrieben - die Quellen dieses Assemblers befinden sich in der Datei crypto/fift/Asm.fif und sind am Anfang des obigen Codeteils verbunden.


Was soll ich sagen, anscheinend liebt Nikolai Durov es einfach, neue Programmiersprachen zu erstellen :)


Erstellen eines intelligenten Vertrags und Interaktion mit TON


Nehmen wir also an, wir haben einen TON-Client und einen Fift-Interpreter wie oben beschrieben zusammengestellt und uns mit der Sprache vertraut gemacht. Wie erstelle ich jetzt einen intelligenten Vertrag? Dies wird in der an die Quelle angehängten HOWTO- Datei beschrieben.


TON-Konten


Wie ich im TON-Test beschrieben habe , enthält dieses Netzwerk mehr als eine Blockchain - es gibt eine gemeinsame, die sogenannte "Master-Kette" sowie eine beliebige Anzahl zusätzlicher "Arbeitsketten", die durch eine 32-Bit-Nummer gekennzeichnet sind. Die Hauptkette hat einen Bezeichner von -1. Zusätzlich kann eine „grundlegende“ Arbeitskette mit dem Bezeichner 0 verwendet werden. Jede Arbeitskette kann eine eigene Konfiguration haben. Intern ist jede Arbeitsgruppe in Shardchains unterteilt, dies ist jedoch bereits ein Detail der Implementierung, das nicht berücksichtigt werden muss.


Viele Konten werden in einer Arbeitskette gespeichert, die ihre eigenen account_id-IDs haben. Für die Masterkette und die Nullarbeitskette haben sie eine Länge von 256 Bit. So wird die Konto-ID beispielsweise wie folgt geschrieben:


 -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d 

Dies ist ein "rohes" Format: zuerst die Arbeitskettenkennung, dann ein Doppelpunkt und die Kontokennung in hexadezimaler Schreibweise.


Darüber hinaus gibt es ein verkürztes Format: Die Arbeitskettennummer und die Kontoadresse werden in binärer Form codiert, eine Prüfsumme wird hinzugefügt und all dies wird in Base64 codiert:


 Ef+BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb 

Wenn wir dieses Aufzeichnungsformat kennen, können wir den aktuellen Status eines Kontos über einen Testclient mit dem Befehl anfordern


 getaccount -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d 

Wir bekommen eine Antwort wie diese:


 [ 3][t 2][1558746708.815218925][test-lite-client.cpp:631][!testnode] requesting account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D [ 3][t 2][1558746708.858564138][test-lite-client.cpp:652][!testnode] got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F and (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F account state is (account addr:(addr_std anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D) storage_stat:(storage_info used:(storage_used cells:(var_uint len:1 value:3) bits:(var_uint len:2 value:539) public_cells:(var_uint len:0 value:0)) last_paid:0 due_payment:nothing) storage:(account_storage last_trans_lt:74208000003 balance:(currencies grams:(nanograms amount:(var_uint len:7 value:999928362430000)) other:(extra_currencies dict:hme_empty)) state:(account_active ( split_depth:nothing special:nothing code:(just value:(raw@^Cell x{} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} )) data:(just value:(raw@^Cell x{} x{0000000D} )) library:hme_empty)))) x{CFF8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D2068086C000000000000000451C90E00DC0E35B7DB5FB8C134_} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} x{0000000D} -client.cpp: [ 3][t 2][1558746708.815218925][test-lite-client.cpp:631][!testnode] requesting account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D [ 3][t 2][1558746708.858564138][test-lite-client.cpp:652][!testnode] got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F and (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F account state is (account addr:(addr_std anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D) storage_stat:(storage_info used:(storage_used cells:(var_uint len:1 value:3) bits:(var_uint len:2 value:539) public_cells:(var_uint len:0 value:0)) last_paid:0 due_payment:nothing) storage:(account_storage last_trans_lt:74208000003 balance:(currencies grams:(nanograms amount:(var_uint len:7 value:999928362430000)) other:(extra_currencies dict:hme_empty)) state:(account_active ( split_depth:nothing special:nothing code:(just value:(raw@^Cell x{} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} )) data:(just value:(raw@^Cell x{} x{0000000D} )) library:hme_empty)))) x{CFF8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D2068086C000000000000000451C90E00DC0E35B7DB5FB8C134_} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} x{0000000D} für -1: 8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D mit Bezug auf die Blöcke (-1,8000000000000000,72355): F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296: 1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F und [ 3][t 2][1558746708.815218925][test-lite-client.cpp:631][!testnode] requesting account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D [ 3][t 2][1558746708.858564138][test-lite-client.cpp:652][!testnode] got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F and (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F account state is (account addr:(addr_std anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D) storage_stat:(storage_info used:(storage_used cells:(var_uint len:1 value:3) bits:(var_uint len:2 value:539) public_cells:(var_uint len:0 value:0)) last_paid:0 due_payment:nothing) storage:(account_storage last_trans_lt:74208000003 balance:(currencies grams:(nanograms amount:(var_uint len:7 value:999928362430000)) other:(extra_currencies dict:hme_empty)) state:(account_active ( split_depth:nothing special:nothing code:(just value:(raw@^Cell x{} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} )) data:(just value:(raw@^Cell x{} x{0000000D} )) library:hme_empty)))) x{CFF8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D2068086C000000000000000451C90E00DC0E35B7DB5FB8C134_} x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} x{0000000D} 

Wir sehen die Struktur, die im DHT der angegebenen Arbeitskette gespeichert ist. Im Feld storage.balance befindet sich beispielsweise der aktuelle Kontostand, in storage.state.code der intelligente Vertragscode und in storage.state.data die aktuellen Daten. Beachten Sie, dass der TON-Datenspeicher - Zelle, Zellen - ein Baum ist. Jede Zelle kann ihre eigenen Daten sowie untergeordnete Zellen haben. Dies wird in den letzten Zeilen als Einrückung angezeigt.


Intelligente Vertragsmontage


Lassen Sie uns nun selbst eine solche Struktur (sie heißt BOC - Bag of Cells ) mit der Sprache Fift erstellen. Glücklicherweise müssen Sie keinen intelligenten Vertrag selbst schreiben. Im Ordner new-wallet.fif crypto/block aus dem new-wallet.fif befindet sich eine Datei new-wallet.fif , mit der wir eine neue Brieftasche erstellen können. Kopieren Sie es mit dem zusammengestellten Client in den Ordner ( ~/liteclient-build , wenn Sie ~/liteclient-build obigen Anweisungen ~/liteclient-build ). Ich habe den Inhalt oben als Beispiel für Code auf Fift zitiert.


Wir führen diese Datei wie folgt aus:


 ./crypto/fift -I"<source-directory>/crypto/fift" new-wallet.fif 

Hier muss <source-directory> durch den Pfad zu den entpackten Quellen ersetzt werden (das Symbol "~" kann hier leider nicht verwendet werden, Sie benötigen leider den vollständigen Pfad). Anstatt den -I Sie die Umgebungsvariable FIFTPATH und diesen Pfad FIFTPATH .


Da wir Fift mit dem Dateinamen new-wallet.fif , wird es ausgeführt und abgeschlossen. Wenn Sie den Dateinamen weglassen, können Sie im interaktiven Modus mit dem Interpreter spielen.


Nach der Ausführung sollte in der Konsole Folgendes angezeigt werden:


 StateInit: x{34_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} new wallet address = -1 : 4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ signing message: x{00000000} External message for initialization is x{89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} B5EE9C724104030100000000D60002CF89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001001020084FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED5400480000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B6290698B (Saved to file new-wallet-query.boc) die StateInit: x{34_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} new wallet address = -1 : 4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ signing message: x{00000000} External message for initialization is x{89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} B5EE9C724104030100000000D60002CF89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001001020084FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED5400480000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B6290698B (Saved to file new-wallet-query.boc) } StateInit: x{34_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} new wallet address = -1 : 4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ signing message: x{00000000} External message for initialization is x{89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001_} x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54} x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B} B5EE9C724104030100000000D60002CF89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001001020084FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED5400480000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B6290698B (Saved to file new-wallet-query.boc) 

Dies bedeutet, dass die Brieftasche mit der Kennung -1:4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 (oder, was dasselbe ist, 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ erstellt wurde. Der entsprechende Code wird in der new-wallet-query.boc new-wallet.addr new-wallet-query.boc , die Adresse in new-wallet.addr und der private Schlüssel in new-wallet.pk (Vorsicht - beim Neustart des Skripts werden diese Dateien überschrieben).


Natürlich kennt das TON-Netzwerk diese Brieftasche noch nicht, sie wird nur in Form dieser Dateien gespeichert. Jetzt müssen Sie es in das Netzwerk hochladen. Das Problem ist jedoch, dass Sie zum Erstellen eines intelligenten Vertrags eine Provision zahlen müssen und der Kontostand immer noch Null beträgt.


Im Arbeitsmodus wird dieses Problem durch den Kauf von Gramm an der Börse (oder durch das Übertragen von einer anderen Brieftasche) gelöst. Nun, im aktuellen Testmodus wurde ein spezieller Smart-Vertrag gestartet, bei dem Sie einfach so bis zu 20 Gramm verlangen können.


Bildung einer Anfrage an den Smart Contract eines anderen


Fordern Sie dazu einen intelligenten Vertrag an und verteilen Sie die Grammatik nach links und rechts. Im selben crypto/block Ordner befindet sich die Datei testgiver.fif :


 // "testgiver.addr" file>B 256 B>u@ 0x8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d dup constant wallet_addr ."Test giver address = " x. cr 0x4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 constant dest_addr -1 constant wc 0x00000011 constant seqno 1000000000 constant Gram { Gram swap */ } : Gram*/ 6.666 Gram*/ constant amount // bx --> b' ( serializes a Gram amount ) { -1 { 1+ 2dup 8 * ufits } until rot over 4 u, -rot 8 * u, } : Gram, // create a message (NB: 01b00.., b = bounce) <bb{010000100} s, wc 8 i, dest_addr 256 u, amount Gram, 0 9 64 32 + + 1+ 1+ u, "GIFT" $, b> <b seqno 32 u, 1 8 u, swap ref, b> dup ."enveloping message: " <s csr. cr <bb{1000100} s, wc 8 i, wallet_addr 256 u, 0 Gram, b{00} s, swap <ss, b> dup ."resulting external message: " <s csr. cr 2 boc+>B dup Bx. cr "wallet-query.boc" B>file 

Wir speichern es auch im Ordner mit dem zusammengestellten Client, constant dest_addr aber die fünfte Zeile - vor der Zeile " constant dest_addr ". Ersetzen Sie es durch die Adresse der Brieftasche, die Sie zuvor erstellt haben (vollständig, nicht abgekürzt). "-1:" Sie müssen nicht am Anfang schreiben, sondern "0x" am Anfang setzen.


Sie können auch die Zeile 6.666 Gram*/ constant amount ändern - dies ist die Menge in Gramm, die Sie anfordern (nicht mehr als 20). Lassen Sie den Dezimalpunkt, auch wenn Sie eine Ganzzahl angeben.


Schließlich müssen Sie die Zeile 0x00000011 constant seqno . Die erste Nummer hier ist die aktuelle Sequenznummer, die auf dem Konto gespeichert ist, auf dem die Gramm ausgegeben werden. Woher bekommt man es? Starten Sie wie oben erwähnt den Client und führen Sie Folgendes aus:


 last getaccount -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d 

Ganz am Ende stehen die Daten des Smart Contract


 ... x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54} x{0000000D} 

Die Nummer 0000000D (Sie werden mehr haben) ist die Sequenznummer, die in testgiver.fif .


Das war's, speichern Sie die Datei und führen Sie sie aus ( ./crypto/fift testgiver.fif ). Die Ausgabe ist die wallet-query.boc . Dies ist die gebildete Nachricht an den intelligenten Vertrag eines anderen - die Anfrage lautet "Übertragen Sie so viele Gramm auf das eine oder andere Konto".


Mit dem Client laden wir es in das Netzwerk hoch:


 > sendfile wallet-query.boc [ 1][t 1][1558747399.456575155][test-lite-client.cpp:577][!testnode] sending query from file wallet-query.boc [ 3][t 2][1558747399.500236034][test-lite-client.cpp:587][!query] external message status is 1 

Wenn wir jetzt last anrufen und dann erneut den Status des Kontos anfordern, von dem wir nach Gramm gefragt haben, sollten wir feststellen, dass sich die Sequenznummer um eins erhöht hat - dies bedeutet, dass Geld auf unser Konto gesendet wurde.


Der letzte Schritt bleibt: Wir laden den Code unserer Brieftasche (der Kontostand wurde bereits aufgefüllt, aber ohne den intelligenten Vertragscode können wir ihn nicht verwalten). sendfile new-wallet-query.boc - und das war's, Sie haben Ihre eigene Brieftasche im TON-Netzwerk (wenn auch sendfile new-wallet-query.boc nur eine Test-Brieftasche).


Erstellen Sie ausgehende Transaktionen


Um Geld vom Kontostand des erstellten Kontos zu überweisen, gibt es eine crypto/block/wallet.fif , die ebenfalls im Ordner des gesammelten Clients abgelegt werden muss.


Ähnlich wie in den vorherigen Schritten müssen Sie den von Ihnen überwiesenen Betrag, die Adresse des Empfängers (dest_addr) und die Nummer Ihrer Brieftasche anpassen (nach der Initialisierung der Brieftasche beträgt sie 1 und erhöht sich nach jeder ausgehenden Transaktion um 1 - Sie können sie anzeigen, indem Sie den Status Ihres Kontos anfordern). . Für Tests können Sie beispielsweise meine Brieftasche verwenden - 0x4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 .


Wenn Sie ( ./crypto/fift wallet.fif ) ./crypto/fift wallet.fif das Skript die Adresse Ihrer Brieftasche (von der Sie sie übertragen) und ihren privaten Schlüssel aus den Dateien new-wallet.addr und new-wallet.pk und schreibt die empfangene Nachricht in new-wallet-query.boc .


sendfile new-wallet-query.boc die Transaktion direkt auszuführen, rufen wir nach wie vor sendfile new-wallet-query.boc im Client auf. Vergessen Sie danach nicht, den Status der Blockchain ( last ) zu aktualisieren und zu überprüfen, ob sich das Guthaben und die Sequenz unserer Brieftasche geändert haben ( getaccount <account_id> ).


Kontobeschreibung


Das ist alles, jetzt können wir intelligente Verträge in TON erstellen und Anfragen an diese senden. Wie Sie sehen, reicht die aktuelle Funktionalität bereits aus, um beispielsweise eine benutzerfreundlichere Brieftasche mit grafischer Oberfläche zu erstellen (es wird jedoch erwartet, dass sie als Teil des Messenger verfügbar sein wird).

Source: https://habr.com/ru/post/de453714/


All Articles