Ana içeriğe geç

TVM Yükseltmesi 2023.07

ipucu

Bu yükseltme Aralık 2023'te Mainnet'ten çalıştırıldı.

c7

c7, sözleşme yürütümü için gerekli olan yerel bağlam bilgilerini (zaman, lt, ağ yapılandırmaları vb) saklayan kayıttır.

c7 demeti, 10'dan 14 elemana genişletilmiştir:

  • 10: Akıllı sözleşmenin kodunun bulunduğu cell.
  • 11: [integer, maybe_dict]: Gelen mesajın TON değeri, ekstra para birimi.
  • 12: integer, depolama aşamasında toplanan ücretler.
  • 13: Önceki bloklar hakkında bilgi içeren tuple.

10: Şu anda akıllı sözleşmenin kodu, yalnızca yürütülebilir bir devam olarak TVM seviyesinde sunulmakta ve hücreye dönüştürülemez. Bu kod, genellikle aynı türdeki bir komşu sözleşmeyi yetkilendirmek için kullanılır; örneğin jetton-cüzdan, jetton-cüzdanı yetkilendirir. Şu an için, depolama ve init_wrapper'ı daha zahmetli hale getiren kod hücresini açıkça depolamamız gerekiyor. 10'u kod için kullanmak, Everscale güncellemesi ile uyumludur.

bilgi

11: Şu an için, gelen mesajın değeri TVM başlatmasından sonra yığında sunulmaktadır. Yürütme sırasında gerekiyorsa, ya bunu küresel bir değişkende saklamak ya da yerel değişkenler aracılığıyla geçirecek biri olmalıdır (funC seviyesinde bu, tüm işlevlerde ek msg_value argümanı gibi görünmektedir). Bunu 11 elemanına koyarak, sözleşme bakiyesi davranışını tekrar edeceğiz: bu, hem yığında hem de c7'de sunulmaktadır.

  • 12: Şu anda depolama ücretlerini hesaplamanın tek yolu, önceki işlemdeki bakiyeyi saklamak, önceki işlemdeki gaz kullanımını bir şekilde hesaplamak ve ardından mevcut bakiyeyi mesaj değerinden çıkarmaktır. Bu arada, depolama ücretlerini hesaplamak sıklıkla istenir.

Önceki Bloklar Hakkında Bilgi

13: Şu anda önceki bloklar hakkında veri alma yolu yoktur. TON'un öldürücü özelliklerinden biri, her yapının bir Merkle kanıt dostu hücreler çantası (ağaç) olmasıdır; ayrıca TVM de hücre ve Merkle kanıt dostudur. Bu şekilde, bloklar hakkında bilgileri TVM bağlamına dahil edersek, birçok güvenilmez senaryo oluşturmak mümkün olacaktır:

  • Sözleşme A, sözleşme B üzerindeki işlemleri inceleyebilir (B'nin iş birliği olmadan).
  • Bozulmuş mesaj zincirlerini geri yüklemek mümkündür (geri yükleme sözleşmesi bazı işlemlerin gerçekleştirildiğini ancak geri alındığını kanıtlarla kontrol eder).
  • Bazı doğrulama balıkçı fonksiyonları onchain'de yapabilmek için ana zincir blok hash'lerini bilmek de gereklidir.

Blok kimlikleri aşağıdaki formatta sunulmaktadır:

[ wc:Integer shard:Integer seqno:Integer root_hash:Integer file_hash:Integer ] = BlockId;
[ last_mc_blocks:[BlockId0, BlockId1, ..., BlockId15]
prev_key_block:BlockId ] : PrevBlocksInfo

Ana zincirin son 16 blokunun kimlikleri (veya ana zincir seqno'su 16'dan azsa daha az) ile birlikte son anahtar bloğu dahil edilir. Shard bloklar hakkında veri dahil edilmesi bazı veri erişebilirlik sorunlarına yol açabilir (birleştirme/ayırma olayları nedeniyle), bu gerekli değildir (herhangi bir olay/veri ana zincir blokları kullanılarak kanıtlanabilir) ve bu nedenle dahil etmeme kararı aldık.


Yeni opcode'lar

Yeni opcode'lar için gaz maliyeti seçerken genel kural, normalden (opcode uzunluğuna göre hesaplanmış) daha az olmaması ve gaz birimi başına 20 ns'den fazla olmamasıdır.

Yeni c7 değerleri ile çalışacak opcode'lar

Her biri için 26 gaz, yalnızca PREVMCBLOCKS ve PREVKEYBLOCK için 34 gaz.

xxxxxxxxxxxxxxxxxxxxxxFift sözdizimixxxxxxxxxYığınxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAçıklama
MYCODE- cc7'den akıllı sözleşmenin kodunu alır
INCOMINGVALUE- tc7'den gelen mesajın değerini alır
STORAGEFEES- ic7'den depolama aşaması ücretlerinin değerini alır
PREVBLOCKSINFOTUPLE- tc7'den PrevBlocksInfo: [last_mc_blocks, prev_key_block] alır
PREVMCBLOCKS- tYalnızca last_mc_blocks alır
PREVKEYBLOCK- tYalnızca prev_key_block alır
GLOBALID- i19 ağ yapılandırmasından global_id alır

Gaz

xxxxxxxxxxxxxxFift sözdizimixxxxxxxxYığınxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAçıklama
GASCONSUMED- g_cŞu ana kadar (bu talimat dahil) VM tarafından tüketilen gazı döndürür.26 gaz

Aritmetik

Yeni bölme opcode'u (A9mscdf) çeşitleri eklenmiştir: d=0, yığından ek bir tam sayı alır ve bölme/rshift öncesinde ara değere ekler. Bu işlemler hem bölüm hem de kalanı döndürür (tam olarak d=3 gibi).

tehlike

Sessiz (quiet) versiyonlar da mevcuttur (örneğin QMULADDDIVMOD veya QUIET MULADDDIVMOD).

Dönüş değerleri, 257-bit tamsayılara sığmazsa veya bölüm sıfırsa, sessiz işlem bir tam sayı taşma istisnası atar. Sessiz işlemler, sığmayan değer yerine NaN döner (bölüm sıfırsa iki tane NaN).

Gaz maliyeti opcode uzunluğu eklenen 10'a eşittir: çoğu opcode için 26, LSHIFT#/RSHIFT# için +8, +8 sessiz için.

xxxxxxxxxxxxxxxxxxxxxxFift sözdizimixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxYığın
MULADDDIVMODx y w z - q=floor((xy+w)/z) r=(xy+w)-zq
MULADDDIVMODRx y w z - q=round((xy+w)/z) r=(xy+w)-zq
MULADDDIVMODCx y w z - q=ceil((xy+w)/z) r=(xy+w)-zq
ADDDIVMODx w z - q=floor((x+w)/z) r=(x+w)-zq
ADDDIVMODRx w z - q=round((x+w)/z) r=(x+w)-zq
ADDDIVMODCx w y - q=ceil((x+w)/z) r=(x+w)-zq
ADDRSHIFTMODx w z - q=floor((x+w)/2^z) r=(x+w)-q*2^z
ADDRSHIFTMODRx w z - q=round((x+w)/2^z) r=(x+w)-q*2^z
ADDRSHIFTMODCx w z - q=ceil((x+w)/2^z) r=(x+w)-q*2^z
z ADDRSHIFT#MODx w - q=floor((x+w)/2^z) r=(x+w)-q*2^z
z ADDRSHIFTR#MODx w - q=round((x+w)/2^z) r=(x+w)-q*2^z
z ADDRSHIFTC#MODx w - q=ceil((x+w)/2^z) r=(x+w)-q*2^z
MULADDRSHIFTMODx y w z - q=floor((xy+w)/2^z) r=(xy+w)-q*2^z
MULADDRSHIFTRMODx y w z - q=round((xy+w)/2^z) r=(xy+w)-q*2^z
MULADDRSHIFTCMODx y w z - q=ceil((xy+w)/2^z) r=(xy+w)-q*2^z
z MULADDRSHIFT#MODx y w - q=floor((xy+w)/2^z) r=(xy+w)-q*2^z
z MULADDRSHIFTR#MODx y w - q=round((xy+w)/2^z) r=(xy+w)-q*2^z
z MULADDRSHIFTC#MODx y w - q=ceil((xy+w)/2^z) r=(xy+w)-q*2^z
LSHIFTADDDIVMODx w z y - q=floor((x*2^y+w)/z) r=(x*2^y+w)-zq
LSHIFTADDDIVMODRx w z y - q=round((x*2^y+w)/z) r=(x*2^y+w)-zq
LSHIFTADDDIVMODCx w z y - q=ceil((x*2^y+w)/z) r=(x*2^y+w)-zq
y LSHIFT#ADDDIVMODx w z - q=floor((x*2^y+w)/z) r=(x*2^y+w)-zq
y LSHIFT#ADDDIVMODRx w z - q=round((x*2^y+w)/z) r=(x*2^y+w)-zq
y LSHIFT#ADDDIVMODCx w z - q=ceil((x*2^y+w)/z) r=(x*2^y+w)-zq

Yığın İşlemleri

Şu anda tüm yığın işlemlerinin argümanları 256 ile sınırlıdır. Bu, yığın derinliği 256'dan fazla olduğunda derin yığın öğelerini yönetmenin zor olduğu anlamına gelir. Çoğu durumda, bu sınır için güvenlik nedenleri yoktur, yani argümanlar aşırı maliyetli işlemleri önlemek için sınırlı değildir.

not

ROLLREV gibi bazı toplu yığın işlemleri için (burada hesaplama süresi doğrusal olarak argüman değerine bağlıdır), gaz maliyeti de argüman değerine doğrusal olarak bağlıdır.

  • PICK, ROLL, ROLLREV, BLKSWX, REVX, DROPX, XCHGX, CHKDEPTH, ONLYTOPX, ONLYX argümanlarının artık sınırsızdır.
  • ROLL, ROLLREV, REVX, ONLYTOPX büyük argümanlar kullanıldığında daha fazla gaz tüketmektedir: ek gaz maliyeti max(arg-255,0) (256'dan az olan argüman için gaz tüketimi sabit ve mevcut davranışa karşılık gelmektedir).
  • BLKSWX için ek maliyet max(arg1+arg2-255,0)'dır (mevcut davranışla örtüşmediğinden, çünkü şu anda hem arg1 hem de arg2 255 ile sınırlıdır).

Hash'ler

Şu anda TVM'de yalnızca iki hash işlemi mevcuttur: hücre/şerit temsil hash'sinin hesaplanması ve verinin sha256'sı, ancak yalnızca 127 byte'a kadar (bu kadar veri yalnızca bir hücreye sığar).

ipucu

HASHEXT[A][R]_(HASH) ailesi işlemleri eklenmiştir:

xxxxxxxxxxxxxxxxxxxFift sözdizimixxxxxxxxxxxxxxxxxxxxxxYığınxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAçıklama
HASHEXT_(HASH)s_1 ... s_n n - hs_1...s_n dilimlerinin (veya oluşturucuların) birleştirilmiş hash'ını hesaplar ve döndürür.
HASHEXTR_(HASH)s_n ... s_1 n - hAynı işlem, ancak argümanlar ters sırada verilir.
HASHEXTA_(HASH)b s_1 ... s_n n - b'Hesaplanan hash'ı bir oluşturucu b'ye ekler, yığına itmek yerine.
HASHEXTAR_(HASH)b s_n ... s_1 n - b'Argümanlar ters sırada verilir, oluşturucuya hash ekler.

s_i'nin kök hücrelerinden yalnızca bitler kullanılır.

Her parça s_i, tam sayı olmayan byte sayısını içerebilir. Ancak, tüm parçaların bit toplamı 8'e tam olarak bölünebilir olmalıdır. TON, en anlamlı bit sıralaması kullanır, bu nedenle tam sayı olmayan byte sayısına sahip iki dilim birleştirildiğinde, ilk dilimden bitler en anlamlı bitler haline gelir.

Gaz tüketimi, hash'lenen byte sayısına ve seçilen algoritmaya bağlıdır. Her bir parça için ek olarak 1 gaz birimi tüketilir.

[A] etkin değilse, hash'in sonucu 256 bit sığarsa imzalı bir tam sayı olarak döndürülür, aksi takdirde tamsayılar tuple olarak döner.

Mevcut Algoritmalar

Aşağıdaki algoritmalar mevcuttur:

  • SHA256 - openssl implementasyonu, byte başına 1/33 gaz, hash 256 bit.
  • SHA512 - openssl implementasyonu, byte başına 1/16 gaz, hash 512 bit.
  • BLAKE2B - openssl implementasyonu, byte başına 1/19 gaz, hash 512 bit.
  • KECCAK256 - ethereum uyumlu implementasyon, byte başına 1/11 gaz, hash 256 bit.
  • KECCAK512 - ethereum uyumlu implementasyon, byte başına 1/6 gaz, hash 512 bit.

Gaz kullanımı aşağı yuvarlanır.


Kripto

Şu anda mevcut olan tek kriptografik algoritma CHKSIGN: h hash'inin Ed25519 imzasını bir genel anahtar k için kontrol eder.

tehlike
  • Önceki nesil blok zincirleri ile uyumluluk için, Bitcoin ve Ethereum gibi secp256k1 imzalarını kontrol etmemiz de gerekmektedir.
  • Modern kriptografik algoritmalar için, en azından eğri toplama ve çarpma gereklidir.
  • Ethereum 2.0 PoS ve diğer bazı modern kriptografi ile uyumluluk için, bls12-381 eğrisi üzerinde BLS imza şemasına ihtiyacımız var.
  • Bazı güvenli donanımlar için secp256r1 == P256 == prime256v1 gereklidir.

secp256k1

Bitcoin/ethereum imzaları. libsecp256k1 implementasyonu kullanır.

xxxxxxxxxxxxxFift sözdizimixxxxxxxxxxxxxxxxxYığınxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAçıklama
ECRECOVERhash v r s - 0 veya h x1 x2 -1İmzadan genel anahtarı kurtarır, Bitcoin/Ethereum işlemleri ile aynıdır.32 byte hash'i hash olarak uint256; 65 byte imza olarak uint8 v ve uint256 r, s alır.Başarısızlıkta 0, başarıda genel anahtar ve -1 döndürür.65 byte genel anahtar uint8 h, uint256 x1, x2 olarak döndürülür.1526 gaz

secp256r1

OpenSSL implementasyonunu kullanır. Arayüz CHKSIGNS/CHKSIGNU ile benzerdir. Apple Secure Enclave ile uyumludur.

xxxxxxxxxxxxxFift sözdizimixxxxxxxxxxxxxxxxxYığınxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAçıklama
P256_CHKSIGNSd sig k - ?Dilim d'nin veri kısmının ve genel anahtar k'nin sig'inin seck256r1 imzasını kontrol eder. Başarıda -1, başarısızlıkta 0 döndürür.Genel anahtar 33 byte'lık bir dilimdir ( SECG SEC 1 bölüm 2.3.4 nokta 2'ye göre kodlanmıştır).İmza sig, iki 256-bit tamsayı r ve s olan 64 byte'lık bir dilimdir.3526 gaz
P256_CHKSIGNUh sig k - ?Aynı işlem, ancak imzalı veri 256-bit işaretsiz tam sayı h'nin 32 byte'lık kodlamasıdır.3526 gaz

Ristretto

Genişletilmiş belgeler burada bulunmaktadır. Kısacası, Curve25519 performans dikkate alınarak geliştirildi, ancak birden fazla temsile sahip olduğu için simetri sergilemektedir. Daha basit protokoller, Schnorr imzaları veya Diffie-Hellman gibi bazı sorunları azaltmak için protokol düzeyinde hileler uygular, ancak anahtar türetme ve anahtar karartma şemalarını bozar. Ve bu hileler, Bulletproofs gibi daha karmaşık protokoller için ölçeklenemez. Ristretto, her grup öğesinin benzersiz bir noktaya karşılık geldiği şekilde Curve25519 üzerinde bir aritmetik soyutlama sağlar; bu, çoğu kriptografik protokol için gereklidir. Ristretto, Curve25519 için gerekli aritmetik soyutlamayı sunan bir sıkıştırma/açma protokolüdür. Sonuç olarak, kripto protokollerinin doğru yazılması kolaydır ve aynı zamanda Curve25519'un yüksek performansından yararlanırlar.

Ristretto işlemleri, Curve25519 üzerinde eğri işlemleri hesaplamayı sağlar (tersi doğru değildir), bu nedenle hem Ristretto'yu hem de Curve25519 eğri işlemini tek adımda eklediğimizi düşünebiliriz.

libsodium implementasyonu kullanılmaktadır.

Tüm ristretto-255 noktaları TVM'de 256-bit imzalı tam sayılar olarak temsil edilmektedir. Sessiz (quiet) işlemler geçerli kodlanmış noktalar değilse range_chk atar. Sıfır noktası tam sayı 0 olarak temsil edilir.

xxxxxxxxxxxxxFift sözdizimixxxxxxxxxxxxxxxxxYığınxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAçıklama
RIST255_FROMHASHh1 h2 - x512-bit hash'den (iki 256-bit tam sayı olarak verilen) deterministik olarak geçerli bir nokta x oluşturur.626 gaz
RIST255_VALIDATEx -Tam sayı x'nin geçerli bir eğri noktası olup olmadığını kontrol eder. Hata durumunda range_chk atar.226 gaz
RIST255_ADDx y - x+yEğri üzerindeki iki noktanın toplamını hesaplar.626 gaz
RIST255_SUBx y - x-yEğri üzerindeki iki noktanın farkını hesaplar.626 gaz
RIST255_MULx n - x*nNokta x'yi n skalar ile çarpar.Herhangi bir n geçerlidir, negatif olanlar dâhildir.2026 gaz
RIST255_MULBASEn - g*nÜretici noktası g'yi n skalar ile çarpar.Herhangi bir n geçerlidir, negatif olanlar dâhildir.776 gaz
RIST255_PUSHL- lKümenin sırasını temsil eden l=2^252+27742317777372353535851937790883648493 değerini yığına iter.26 gaz
RIST255_QVALIDATEx - 0 veya -1Sessiz (quiet) sürümü RIST255_VALIDATE.234 gaz
RIST255_QADDx y - 0 veya x+y -1Sessiz (quiet) sürümü RIST255_ADD. 634 gaz
RIST255_QSUBx y - 0 veya x-y -1Sessiz (quiet) sürümü RIST255_SUB.634 gaz
RIST255_QMULx n - 0 veya x*n -1Sessiz (quiet) sürümü RIST255_MUL.2034 gaz
RIST255_QMULBASEn - 0 veya g*n -1Sessiz (quiet) sürümü RIST255_MULBASE.784 gaz

BLS12-381

Eşleme dostu BLS12-381 eğrisi üzerindeki işlemler. BLST implementasyonu kullanılmaktadır. Ayrıca, bu eğriye dayalı BLS imza şeması için ops sağlanmaktadır.

BLS değerleri TVM'de şu şekilde temsil edilmektedir:

  • G1-points ve genel anahtarlar: 48 byte dilim.
  • G2-points ve imzalar: 96 byte dilim.
  • FP alanının elemanları: 48 byte dilim.
  • FP2 alanının elemanları: 96 byte dilim.
  • Mesajlar: dilim. Bit sayısı 8'e bölünebilir olmalıdır.

Giriş değeri bir nokta veya bir alan elemanı olduğunda, dilim 48/96 byte'dan fazla olabilir. Bu durumda yalnızca ilk 48/96 byte alınır. Eğer dilim daha az byte içerirse (veya mesaj boyutu 8'e bölünemiyorsa), hücre alt akışı istisnası atılır.

Yüksek Seviyeli İşlemler

Bunlar BLS imzalarını doğrulamak için yüksek seviyeli işlemlerdir.

xxxxxxxxxxxxxFift sözdizimixxxxxxxxxxxxxxxxxYığınxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAçıklama
BLS_VERIFYpk msg sgn - boolBLS imzasını kontrol eder, başarıda true, aksi halde false döndürür.61034 gaz
BLS_AGGREGATEsig_1 ... sig_n n - sigİmzaları toplar. n>0. n=0 veya sig_i'den biri geçerli bir imza değilse istisna fırlatır.gaz=n*4350-2616
BLS_FASTAGGREGATEVERIFY-pk_1 ... pk_n n msg sig - boolAnahtarlar pk_1...pk_n ve mesaj msg için toplu BLS imzasını kontrol eder. Başarısızlıkta false döner, n=0 ise false döner.gaz=58034+n*3000
BLS_AGGREGATEVERIFYpk_1 msg_1 ... pk_n msg_n n sgn - boolAnahtar-mesaj çifti pk_1 msg_1...pk_n msg_n için toplu BLS imzasını kontrol eder. Başarısızlıkta false döner, n=0 ise false döner.gaz=38534+n*22500
tehlike

VERIFY talimatları geçersiz imza ve genel anahtarlar üzerinde istisna atmaz (hücre alt akış istisnaları dışında), bunun yerine false döner.

Düşük seviye işlemler

Bunlar, grup elemanları üzerinde yapılan aritmetik işlemlerdir.

xxxxxxxxxxxxxFift sözdizimixxxxxxxxxxxxxxxxxYığınxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAçıklama
BLS_G1_ADDx y - x+yG1 üzerinde toplama.3934 gaz
BLS_G1_SUBx y - x-yG1 üzerinde çıkarma.3934 gaz
BLS_G1_NEGx - -xG1 üzerinde olumsuzlama.784 gaz
BLS_G1_MULx s - x*sG1 noktasını x skalar s ile çarpar.Herhangi bir s geçerlidir, negatif olanlar da dahil.5234 gaz

| BLS_G1_MULTIEXP | x_1 s_1 ... x_n s_n n - x_1*s_1+...+x_n*s_n | G1 noktaları x_i ve skalarlar s_i için x_1*s_1+...+x_n*s_n hesaplar. n=0 ise sıfır noktası döner.Herhangi bir s_i geçerlidir, negatif olanlar da dahil.gaz=11409+n*630+n/floor(max(log2(n),4))*8820 || BLS_G1_ZERO | - sıfır | G1'de sıfır noktasını iteler.34 gaz | | BLS_MAP_TO_G1 | f - x | FP elemanı f'yi G1 noktasına dönüştürür.2384 gaz | | BLS_G1_INGROUP | x - bool | Dilim x'nin G1'in geçerli bir elemanını temsil edip etmediğini kontrol eder.2984 gaz | | BLS_G1_ISZERO | x - bool | G1 noktası x'nin sıfıra eşit olup olmadığını kontrol eder.34 gaz | | BLS_G2_ADD | x y - x+y | G2 üzerinde toplama.6134 gaz | | BLS_G2_SUB | x y - x-y | G2 üzerinde çıkarma.6134 gaz | | BLS_G2_NEG | x - -x | G2 üzerinde olumsuzlama.1584 gaz | | BLS_G2_MUL | x s - x*s | G2 noktasını x skalar s ile çarpar.Herhangi bir s geçerlidir, negatif olanlar da dahil.10584 gaz | | BLS_G2_MULTIEXP | x_1 s_1 ... x_n s_n n - x_1*s_1+...+x_n*s_n | G2 noktaları x_i ve skalarlar s_i için x_1*s_1+...+x_n*s_n hesaplar. n=0 ise sıfır noktası döner.Herhangi bir s_i geçerlidir, negatif olanlar da dahil.gaz=30422+n*1280+n/floor(max(log2(n),4))*22840 | | BLS_G2_ZERO | - sıfır | G2'de sıfır noktasını iteler.34 gaz | | BLS_MAP_TO_G2 | f - x | FP2 elemanı f'yi G2 noktasına dönüştürür.7984 gaz | | BLS_G2_INGROUP | x - bool | Dilim x'nin G2'nin geçerli bir elemanını temsil edip etmediğini kontrol eder.4284 gaz | | BLS_G2_ISZERO | x - bool | G2 noktası x'nin sıfıra eşit olup olmadığını kontrol eder.34 gaz | | BLS_PAIRING | x_1 y_1 ... x_n y_n n - bool | G1 noktaları x_i ve G2 noktaları y_i verilen, x_i,y_i eşleşmelerini hesaplar ve çarpar. Sonuç FP12'de çarpan kimliği ise doğru döner, aksi halde yanlış döner. n=0 ise yanlış döner.gaz=20034+n*11800 | | BLS_PUSHR | - r | G1 ve G2'nin sırasını iteler (yaklaşık 2^255).34 gaz |

tehlike

INGROUP, ISZERO geçersiz noktalar üzerinde istisna atmaz (hücre alt akış istisnaları dışında), bunun yerine yanlış döner. Diğer aritmetik işlemler geçersiz eğri noktaları üzerinde istisna atar. Verilen eğri noktalarının G1/G2 grubuna ait olup olmadığını kontrol etmezler. Bunu kontrol etmek için INGROUP talimatını kullanın.


RUNVM

Şu anda, TVM'deki kodun dışarıdan güvenilmeyen kodu "sandık içinde" çağırmasının bir yolu yok. Başka bir deyişle, harici kod her zaman sözleşmenin kodunu, verilerini veya tüm parayı gönderme gibi eylemleri geri dönüşü olmayan bir şekilde güncelleyebilir.

RUNVM talimatı, bağımsız bir VM örneği başlatmayı, istenen kodu çalıştırmayı ve gereken verileri (yığın, kayıtlar, gaz tüketimi vb.) çağıranın durumunu kirletmeden almayı sağlar. Rastgele kodu güvenli bir şekilde çalıştırmak, v4 tarzı eklentiler, Tact'ın init tarzı alt sözleşme hesaplama gibi durumlar için faydalı olabilir.

xxxxxxxxxxxxxFift sözdizimixxxxxxxxxxxxxxxxxYığınxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAçıklama
flags RUNVMx_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c]code ve yığın x_1...x_n ile çocuk VM'i çalıştırır. Sonuç yığınını x'_1...x'_m ve çıkış kodunu döner.Diğer argümanlar ve dönüş değerleri, aşağıda belirtilen bayraklarla etkinleştirilir.
RUNVMXx_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] flags - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c]Aynı şey, ancak bayrakları yığından çıkarır.

Bayraklar, fift'teki runvmx ile benzer:

  • +1: c3'ü koda ayarla
  • +2: kodu çalıştırmadan önce bir örtük 0 ekle
  • +4: yığından c4'ü al (kalıcı veri), nihai değerini döner
  • +8: yığından gaz limitini g_l al, kullanılan gazı g_c döner
  • +16: yığından c7'yi al (akıllı sözleşme bağlamı)
  • +32: c5'in nihai değerini döner (hareketler)
  • +64: yığından zor gaz limitini g_m çıkar (KABUL ile etkinleşmiştir)
  • +128: "izole gaz tüketimi". Çocuk VM ayrı bir ziyaret edilen hücreler setine ve ayrı bir chksgn sayacına sahip olacaktır.
  • +256: tam olarak r değerini döndür, yığının tepe noktasından r değerini çıkar:
    - RUNVM çağrısı başarılı ise ve `r` ayarlanmışsa, `r` eleman döner. Eğer `r` ayarlanmamışsa - tümünü döner;
    - RUNVM başarılıdır ama yığında yeterli eleman yoksa (yığın derinliği `r`'den az) bu çocuk VM'de bir istisna olarak kabul edilir, çıkış_kodu=-3 ve çıkış_argümanı=0 (0, tek yığın elemanı olarak döner);
    - RUNVM, istisna ile başarısız olursa - yalnızca bir eleman döner - çıkış argümanı (çıkış kodu ile karıştırılmamalıdır);
    - OOG durumunda ise, çıkış_kodu = -14 ve çıkış_argümanı gaz miktarıdır.
not

Gaz maliyeti:

  • 66 gaz
  • Çocuk VM'e verilen her yığın elemanı için 1 gaz (ilk 32 ücretsiz)
  • Çocuk VM'den dönen her yığın elemanı için 1 gaz (ilk 32 ücretsiz)

Mesaj gönderme

Şu anda, bir sözleşmede mesaj gönderme maliyetini hesaplamak zordur (bu da bazı yaklaşık hesaplamalara neden olur, örneğin jettons) ve eylem aşaması yanlışsa isteğin geri dönüşünü sağlamak imkansızdır. Ayrıca, "sözleşme mantığı için sabit ücret" ve "gaz masraflarından" gelen mesajın toplamından doğru bir şekilde çıkarmak da imkansızdır.

  • SENDMSG, bir hücre ve mod olarak giriş alır. Bir çıkış eylemi oluşturur ve bir mesaj oluşturma ücreti döner. Mod, SENDRAWMSG durumundaki etkiyle aynı etkiye sahiptir. Ek olarak, +1024 demek - bir eylem oluşturma, yalnızca ücreti tahmin et. Diğer modlar, ücret hesaplamalarını şu şekilde etkiler: +64 gelen mesajın tüm bakiyesinin çıkış değeri olarak değiştirilmesini sağlar (hafif hatalı, hesaplama tamamlanmadan önce tahmin edilemeyen gaz masrafları hesaba katılmamaktadır), +128 ise hesaplama aşamasının başlangıcından önce sözleşmenin bakiyesinin tüm değerini değiştirilmesini sağlar (hafif hatalı, çünkü hesaplama aşaması tamamlanmadan önce tahmin edilemeyen gaz masrafları hesaba katılmamaktadır).
  • SENDRAWMSG, RAWRESERVE, SETLIBCODE, CHANGELIB - +16 bayrağı eklenir, bu demektir ki eylem başarısız olursa - işlemi geri döner. +2 kullanıldığında hiçbir etkisi yoktur.