Sertleştirilmiş JavaScript
::: tip İzleme: Güvenli Javascript'te Nesne-yetenekli Programlama (Ağustos 2019)
İlk 15 dakika aşağıdaki içeriğin çoğunu kapsar. Son 10 dakika Soru&Cevap'dır.
:::
Örnek Sertleştirilmiş JavaScript Kodu
Aşağıdaki örnek, Sertleştirilmiş JavaScript’in birkaç özelliğini göstermektedir.
:::
Araç Desteği: eslint yapılandırması
::: tip Jessie için eslint yapılandırması
Bu bölümdeki örnekler, JavaScript akıllı sözleşmeleri yazmak için önerilen stilimiz olan Jessie kullanılarak yazılmıştır. Bu eslint
yapılandırması, araç desteği sağlar.
:::
- Boş bir dizinden çalışıyorsanız, önce
yarn init
veyayarn init -y
komutunu çalıştırarak bir package.json dosyası oluşturmalısınız. - Buradan sonra, projeye
yarn add eslint @jessie.js/eslint-plugin
komutunu kullanarak eslint'i yükleyebiliriz. - Son adım, projemizin eslint yapılandırmasını package.json dosyasına eklemektir; aşağıdaki kod bloğunu ekleyin.
"eslintConfig" : {
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 6
},
"extends": [
"plugin:@jessie.js/recommended"
]
}
Artık package.json dosyasının içeriği aşağıdaki örneğe benzer görünmelidir.
{
"name": "eslint-config-test",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"type": "module",
"devDependencies": {
"@jessie.js/eslint-plugin": "^0.1.3",
"eslint": "^8.6.0"
},
"eslintConfig": {
"parserOptions": { "sourceType": "module", "ecmaVersion": 6 },
"extends": ["plugin:@jessie.js/recommended"]
}
}
jessie.js Kodunun Linting'i
.js
kaynak dosyanızın başına// @jessie-check
yazın.yarn eslint --fix path/to/your-source.js
komutunu çalıştırın.- Eğer eslint kodunuzda sorunlar bulursa, linter'ın tavsiyelerine göre dosyanızı düzenleyin ve ardından yukarıdaki adımı tekrarlayın.
Jessie detayları, deneyimle birlikte gelişti. Sonuç olarak, burada (count += 1)
kullanıyoruz, oysa video { return count++; }
gösteriyor.
Nesneler ve maker Deseni
Şimdi makeCounter
örneğini biraz inceleyelim.
JavaScript, nesnelerin herhangi bir sınıfa ait olmasının gerekmemesi açısından biraz yenilikçidir; nesneler sadece kendi başlarına durabilirler:
fn())` yeterli olabilir
- Ayrıca için de bakın.
require
(Bunun yerineimport
modül sözdizimini kullanın.)localStorage
- dikey süreklilik, durumların olağan değişkenler ve veri yapılarında sonsuz süre yaşamasını sağlar ve özel olarak depolamaya yazılması gerekmez.
- Yüksek kartinaliteli veriler için bakın.
global
(Bunun yerineglobalThis
kullanın.)- yetkisiz, ancak ev sahibi tanımlı:
Buffer
URL
veURLSearchParams
TextEncoder
,TextDecoder
WebAssembly
Agoric akıllı sözleşmelerini yüklemek için kullanılan bölmelere, globalThis
sertleşmiş olup OCap disiplinini takip eder.
Bu bölmeler, içindeki console
ve assert
globals’ını içerir. Ancak yazdırma için console.log
kullanmayın; yalnızca hata ayıklama içindir ve blockchain mutabakat bağlamında hiçbir şey yapmayabilir.
Yeni bir Compartment
nesnesi oluşturabilirsiniz. Bunu yaptığınızda, OCap disiplinini uygulayıp uygulamayacağınıza karar verebilir ve harden(compartment.globalThis)
çağrısı yapabilirsiniz. Eğer yapmazsanız, compartment içindeki tüm nesnelerin globalThis'in özellikleri aracılığıyla diğer nesnelerle iletişim kurma yetkisine sahip olduğunu unutmayın.
Türler: Danışmanlık
bazı kodlama hatalarının önlenmesine yardımcı olabilir. Bu stili, tür açıklamalarının yalnızca lint araçları için olduğunu ve çalışma zamanında hiçbir etkisi olmadığını hatırlamak için TypeScript sözdizimi yazmak yerine öneriyoruz:
// @ts-check
/** @param {number} init */
const makeCounter = init => {
let value = init;
return {
incr: () => {
value += 1;
return value;
}
};
};
Eğer dikkatli olmazsak, müşterilerimiz yanlış davranışlar sergileyebilir:
> const evil = makeCounter('poison')
> evil2.incr()
'poison1'
veya daha kötüsü:
> const evil2 = makeCounter({ valueOf: () => { console.log('füzeleri ateşle!'); return 1; } });
> evil2.incr()
füzeleri ateşle!
2
Türler: Savunmacı
Defansif olarak doğru olmak için güven sınırlarını aşan herhangi bir girdi için çalışma zamanı doğrulaması yapmamız gerekmektedir:
import Nat from `@endo/nat`;
/** @param {number | bignum} init */
const makeCounter = init => {
let value = Nat(init);
return harden({
increment: () => {
value += 1n;
return value;
},
});
};
> makeCounter('poison')
Uncaught TypeError: poison is a string but must be a bigint or a number
OCaps'tan Elektronik Haklara: Mint ve Purse
Yukarıdaki Sertleştirilmiş JavaScript teknikleri, ERTP'nin özünü ve güvenlik özelliklerini yalnızca 30 satırda ifade edecek kadar güçlüdür. Bu 8 dakikalık video sunumunun dikkatli incelenmesi, Zoe ile akıllı sözleşmeler yazmak için sağlam bir temel sağlar.
::: tip İzleme: Mint Deseni 8 dakika ,
:::
const makeMint = () => {
const ledger = makeWeakMap();
const issuer = harden({
makeEmptyPurse: () => mint.makePurse(0)
});
const mint = harden({
makePurse: initialBalance => {
const purse = harden({
getIssuer: () => issuer,
getBalance: () => ledger.get(purse),
deposit: (amount, src) => {
Nat(ledger.get(purse) + Nat(amount));
ledger.set(src, Nat(ledger.get(src) - amount));
ledger.set(purse, ledger.get(purse) + amount);
},
withdraw: amount => {
const newPurse = issuer.makeEmptyPurse();
newPurse.deposit(amount, purse);
return newPurse;
}
});
ledger.set(purse, initialBalance);
return purse;
}
});
return mint;
};