ProHoster > blogg > administration > Testa klient TON (Telegram Open Network) och nytt Fift-språk för smarta kontrakt
Testa klient TON (Telegram Open Network) och nytt Fift-språk för smarta kontrakt
För mer än ett år sedan blev det känt om planerna för Telegram Messenger att släppa sitt eget decentraliserade nätverk Telegram Open Network. Sedan blev ett omfattande tekniskt dokument tillgängligt, som påstås ha skrivits av Nikolai Durov och beskrev strukturen för det framtida nätverket. För de som missade det rekommenderar jag att ni läser min återberättelse av detta dokument (Del 1, Del 2; den tredje delen, tyvärr, samlar fortfarande damm i drag).
Sedan dess har det inte kommit några betydande nyheter om statusen för TON-utveckling förrän för ett par dagar sedan (i en av inofficiella kanaler) länken till sidan visades inte https://test.ton.org/download.html, var finns:
◦ ton-test-liteclient-full.tar.xz — Källor till en ljusklient för TON-testnätverket.
◦ ton-lite-client-test1.config.json — Konfigurationsfil för anslutning till testnätverket.
◦ README — Information om att bygga och lansera kunden.
◦ HUR — Steg-för-steg-instruktioner för att skapa ett smart kontrakt med en kund.
◦ ton.pdf — uppdaterat dokument (daterat 2 mars 2019) med en teknisk översikt över TON-nätverket;
◦ tvm.pdf — Teknisk beskrivning av TVM (TON Virtual Machine, TON virtuell maskin).
◦ tblkch.pdf — Teknisk beskrivning av TON-blockkedjan.
◦ fifthbase.pdf — Beskrivning av det nya språket Fift, designat för att skapa smarta kontrakt i TON.
Jag upprepar, det fanns ingen officiell bekräftelse av sidan och alla dessa dokument från Telegram, men volymen av dessa material gör dem ganska rimliga. Starta den publicerade klienten på egen risk.
Bygga en testklient
Låt oss först försöka bygga och köra en testklient - lyckligtvis, README beskriver denna enkla process i detalj. Jag kommer att göra detta med macOS 10.14.5 som ett exempel; jag kan inte garantera framgången med bygget på andra system.
Ladda ner och packa upp källarkiv. Det är viktigt att ladda ner den senaste versionen eftersom bakåtkompatibilitet inte garanteras i detta skede.
Se till att de senaste versionerna av make, cmake (version 3.0.2 eller högre), OpenSSL (inklusive C-huvudfiler), g++ eller clang är installerade på systemet. Jag behövde inte installera något, allt kom ihop direkt.
Låt oss anta att källorna packas upp i en mapp ~/lite-client. Separat från det skapar du en tom mapp för det sammansatta projektet (till exempel, ~/liteclient-build), och från det (cd ~/liteclient-build) anropa kommandona:
Om allt är gjort korrekt bör du se något i stil med detta:
Som vi kan se finns det några tillgängliga kommandon:
◦ help — visa den här listan med kommandon;
◦ quit - gå ut;
◦ time — visa aktuell tid på servern;
◦ status — visa anslutningen och den lokala databasens status;
◦ last — uppdatera blockkedjans tillstånd (ladda ner det sista blocket). Det är viktigt att köra det här kommandot innan några förfrågningar för att vara säker på att du ser det aktuella tillståndet för nätverket.
◦ sendfile<filename> — ladda upp en lokal fil till TON-nätverket. Det är så interaktion med nätverket sker – inklusive till exempel skapandet av nya smarta kontrakt och förfrågningar om att överföra pengar mellan konton;
◦ getaccount<address> — visa strömmen (vid den tidpunkt då kommandot utfördes) last) statusen för kontot med den angivna adressen;
◦ privkey<filename> — ladda den privata nyckeln från en lokal fil.
Om du, när du startar klienten, överför en mapp till den med alternativet -D, så kommer han att lägga till det sista blocket av masterchain i det:
Nu kan vi gå vidare till mer intressanta saker - lär oss Fift-språket, försök att kompilera ett smart kontrakt (till exempel skapa en testplånbok), ladda upp den till nätverket och prova att överföra pengar mellan konton.
Language Fift
Från dokument fifthbase.pdf du kan ta reda på att Telegram-teamet har skapat ett nytt stackspråk för att skapa smarta kontrakt Fift (uppenbarligen från siffran femte, liknande Forth, ett språk med vilket Fifth har mycket gemensamt).
Dokumentet är ganska omfattande, 87 sidor, och jag kommer inte att återberätta innehållet i detalj inom ramen för denna artikel (åtminstone eftersom jag inte har läst klart det själv :). Jag kommer att fokusera på huvudpunkterna och ge ett par kodexempel på detta språk.
På en grundläggande nivå är Fifts syntax ganska enkel: dess kod består av ord, vanligtvis åtskilda av mellanslag eller radbrytningar (speciellt fall: vissa ord kräver inte en avgränsare efter sig). Några слово är en skiftlägeskänslig sekvens av tecken som motsvarar en viss bestämning av (ungefär vad tolken ska göra när den stöter på detta ord). Om det inte finns någon definition av ett ord, försöker tolken analysera det som ett tal och lägga det på högen. Förresten, talen här är - plötsligt - 257-bitars heltal, och det finns inga bråk alls - mer exakt, de förvandlas omedelbart till ett par heltal, som bildar täljaren och nämnaren för ett rationellt bråk.
Ord tenderar att interagera med värden överst i stapeln. En separat typ av ord - prefix — använder inte stacken, utan de efterföljande tecknen från källfilen. Till exempel är det så här strängliteraler implementeras - citattecknet (") är ett prefixord som letar efter nästa (avslutande) citat och skjuter strängen mellan dem på stapeln. Oneliners beter sig på samma sätt (//) och multiline (/*) kommentarer.
Det är här nästan hela språkets interna struktur slutar. Allt annat (inklusive kontrollkonstruktioner) definieras som ord (antingen interna, såsom aritmetiska operationer och definitionen av nya ord; eller definieras i "standardbiblioteket" Fift.fif, som finns i mappen crypto/fift i källorna).
Ett enkelt exempelprogram i Fift:
{ dup =: x dup * =: y } : setxy
3 setxy x . y . x y + .
7 setxy x . y . x y + .
Den första raden definierar ett nytt ord setxy (notera prefixet {, vilket skapar ett block före det avslutande } och prefix :, som faktiskt definierar ordet). setxy tar ett nummer från toppen av stacken, definierar (eller omdefinierar) det som globalt konstantx, och kvadraten på detta tal som en konstant y (Med tanke på att värdena på konstanter kan omdefinieras, skulle jag hellre kalla dem variabler, men jag följer namnkonventionen i språket).
De följande två raderna lägger ett nummer på högen och ringer setxy, då visas värdena för konstanterna x, y (ordet används för utdata .), placeras båda konstanterna på stapeln, summeras, och resultatet skrivs också ut. Som ett resultat kommer vi att se:
3 9 12 ok
7 49 56 ok
(Raden "ok" skrivs ut av tolken när den avslutar bearbetningen av den aktuella raden i interaktivt inmatningsläge)
Denna läskiga fil är till för att skapa ett smart kontrakt - den kommer att placeras i en fil new-wallet-query.boc efter avrättningen. Observera att ett annat sammansättningsspråk används här för TON Virtual Machine (jag kommer inte att uppehålla mig i detalj), vars instruktioner kommer att placeras på blockchain.
Således är assemblern för TVM skriven i Fift - källorna till denna assembler finns i filen crypto/fift/Asm.fif och är anslutna i början av ovanstående kodstycke.
Vad kan jag säga, tydligen älskar Nikolai Durov att skapa nya programmeringsspråk :)
Skapa ett smart kontrakt och interagera med TON
Så låt oss anta att vi har satt ihop TON-klienten och Fift-tolken enligt beskrivningen ovan och blivit bekanta med språket. Hur skapar man ett smart kontrakt nu? Detta beskrivs i filen HUR, bifogat källorna.
Konton i TON
Som jag beskrev i TON recension, detta nätverk innehåller mer än en blockchain - det finns en vanlig, den så kallade. "huvudkedja", samt ett godtyckligt antal ytterligare "arbetskedjor", identifierade med ett 32-bitars nummer. Masterkedjan har en identifierare på -1, utöver den kan en "bas"-arbetskedja med identifieraren 0. Varje arbetskedja kan ha sin egen konfiguration. Internt är varje arbetskedja uppdelad i shardchains, men detta är en implementeringsdetalj som man inte behöver ha i åtanke.
Inom en arbetskedja lagras många konton som har sina egna account_id-identifierare. För masterkedjan och nollarbetskedjan är de 256 bitar långa. Således skrivs kontoidentifieraren till exempel så här:
Detta är det "råa" formatet: först arbetskedjans ID, sedan ett kolon och konto-ID:t i hexadecimal notation.
Dessutom finns det ett förkortat format - arbetskedjans nummer och kontoadressen kodas i binär form, en kontrollsumma läggs till dem, och allt detta kodas i Base64:
Ef+BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb
Genom att känna till detta postformat kan vi begära det aktuella tillståndet för ett konto genom en testklient med kommandot
[ 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}
Vi ser strukturen som är lagrad i DHT för den angivna arbetskedjan. Till exempel i fält storage.balance är bytesbalansen, i storage.state.code - smart avtalskod, och in storage.state.data - dess aktuella data. Observera att TON-datalagringen - Cell, celler - är trädliknande, varje cell kan ha både sina egna data och barnceller. Detta visas som indrag på de sista raderna.
Bygga ett smart kontrakt
Låt oss nu skapa en sådan struktur själva (det kallas BOC - påse med celler) med hjälp av språket Fift. Lyckligtvis behöver du inte skriva ett smart kontrakt själv - i mappen crypto/block det finns en fil från källarkivet new-wallet.fif, som hjälper oss att skapa en ny plånbok. Låt oss kopiera den till mappen med den monterade klienten (~/liteclient-build, om du följde instruktionerna ovan). Jag citerade dess innehåll ovan som ett exempel på kod på Fift.
Här <source-directory> måste ersättas med sökvägen till de uppackade källorna (symbolen "~" kan tyvärr inte användas här, hela sökvägen behövs). Istället för att använda en nyckel -I du kan definiera en miljövariabel FIFTPATH och lägg denna väg in i den.
Sedan vi lanserade Fift med filnamnet new-wallet.fif, kommer den att köra den och avsluta. Om du utelämnar filnamnet kan du spela med tolken interaktivt.
Efter körning bör något i stil med detta visas i konsolen:
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)
Det betyder att plånboken med ID -1:4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 (eller, vad är samma, 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ) har skapats framgångsrikt. Motsvarande kod kommer att finnas i filen new-wallet-query.boc, hans adress finns i new-wallet.addr, och den privata nyckeln är i new-wallet.pk (var försiktig - att köra skriptet igen kommer att skriva över dessa filer).
Naturligtvis känner TON-nätverket ännu inte till denna plånbok, den lagras endast i form av dessa filer. Nu måste den laddas upp till nätverket. Men problemet är att för att skapa ett smart kontrakt måste du betala en provision, och ditt kontosaldo är fortfarande noll.
I arbetsläge kommer detta problem att lösas genom att köpa gram på börsen (eller överföra från en annan plånbok). Jo, i det aktuella testläget har ett speciellt smart kontrakt skapats, från vilket man kan begära upp till 20 gram bara sådär.
Generera en förfrågan till någon annans smarta kontrakt
Vi gör en förfrågan till ett smart kontrakt som delar ut gram vänster och höger så här. I samma mapp crypto/block hitta fil 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
// b x --> 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)
<b b{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
<b b{1000100} s, wc 8 i, wallet_addr 256 u, 0 Gram, b{00} s,
swap <s s, b>
dup ."resulting external message: " <s csr. cr
2 boc+>B dup Bx. cr
"wallet-query.boc" B>file
Vi kommer också att spara det i mappen med den monterade klienten, men vi kommer att korrigera den femte raden - före raden "constant dest_addr". Låt oss ersätta den med adressen till plånboken som du skapade tidigare (fullständig, inte förkortad). Du behöver inte skriva "-1:" i början, lägg istället "0x" i början.
Du kan också ändra linjen 6.666 Gram*/ constant amount — det här är mängden i gram som du begär (högst 20). Även om du anger ett heltal, lämna decimalkomma.
Slutligen måste du korrigera linjen 0x00000011 constant seqno. Det första numret här är det aktuella sekvensnumret, som lagras i kontot som utfärdar gram. Var kan jag få det ifrån? Som nämnts ovan, starta klienten och kör:
last
getaccount -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
I slutet kommer smarta kontraktsdata att innehålla
Siffran 0000000D (ditt kommer att vara större) är sekvensnumret som måste ersättas med testgiver.fif.
Det var allt, spara filen och kör (./crypto/fift testgiver.fif). Utdata kommer att vara en fil wallet-query.boc. Detta är vad som bildas сообщение till någon annans smarta kontrakt - en begäran "överför så många gram till ett sådant och ett konto."
Med hjälp av klienten laddar vi upp den till nätverket:
> 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
Om du nu ringer last, och sedan återigen begära status för kontot som vi bad om gram från, då bör vi se att dess sekvensnummer har ökat med ett - det betyder att det skickade pengar till vårt konto.
Det sista steget återstår - ladda ner koden för vår plånbok (dess saldo har redan fyllts på, men utan den smarta kontraktskoden kommer vi inte att kunna hantera det). Vi genomför sendfile new-wallet-query.boc — och det är det, du har din egen plånbok på TON-nätverket (även om det bara är ett test för tillfället).
Skapa utgående transaktioner
För att överföra pengar från saldot på det skapade kontot finns det en fil crypto/block/wallet.fif, som också måste placeras i mappen med den monterade klienten.
I likhet med de föregående stegen måste du justera beloppet du överför, mottagarens adress (dest_addr) och seqno för din plånbok (den är lika med 1 efter initialisering av plånboken och ökar med 1 efter varje utgående transaktion - du kan se det genom att begära status för ditt konto). För tester kan du använda till exempel min plånbok - 0x4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2.
Vid start (./crypto/fift wallet.fif) skriptet tar adressen till din plånbok (varifrån du överför) och dess privata nyckel från filerna new-wallet.addr и new-wallet.pk, och det mottagna meddelandet kommer att skrivas till new-wallet-query.boc.
Som tidigare, för att direkt utföra transaktionen, ring sendfile new-wallet-query.boc i klienten. Efter detta, glöm inte att uppdatera blockkedjans tillstånd (last) och kontrollera att saldot och seqno på vår plånbok har ändrats (getaccount <account_id>).
Det är allt, nu kan vi skapa smarta kontrakt i TON och skicka förfrågningar till dem. Som du kan se räcker den nuvarande funktionaliteten redan för att till exempel göra en mer användarvänlig plånbok med ett grafiskt gränssnitt (dock förväntas det att den redan kommer att bli tillgänglig som en del av messengern).
Endast registrerade användare kan delta i undersökningen. Logga in, Snälla du.
Är du intresserad av att fortsätta artiklarna med analys av TON, TVM, Fift?
Ja, jag väntar på slutförandet av artikelserien med en allmän översikt över TON
Ja, det är intressant att läsa mer om språket Fift
Ja, jag vill lära mig mer om TON Virtual Machine och assemblern för den
Nej, inget av detta är intressant
39 användare röstade. 12 användare avstod från att rösta.
Vad tycker du om Telegrams planer på att lansera TON?
Jag har stora förhoppningar på det här projektet
Jag följer bara dess utveckling med intresse.
Jag är skeptisk och tvivlar på dess framgång.
Jag är benägen att betrakta detta initiativ som ett misslyckande och onödigt för de breda massorna
47 användare röstade. 12 användare avstod från att rösta.