Utreexo: د ډیری UTXO Bitcoin فشارول

Utreexo: د ډیری UTXO Bitcoin فشارول

اې حبره!

د Bitcoin شبکه کې، ټول نوډونه، د توافق له لارې، د UTXOs په یوه سیټ موافق دي: څومره سکې د لګښت لپاره شتون لري، چا ته په سمه توګه، او د کومو شرایطو لاندې. د UTXO سیټ د تایید کونکي نوډ لپاره اړین ډیټا لږترلږه سیټ دی ، پرته لدې چې نوډ به ونه شي کولی د راتلونکو لیږدونو اعتبار تصدیق کړي او هغه بلاکونه چې پکې شامل دي.

په دې برخه کې، د هرې ممکنې لارې هڅې کیږي چې د دې سیټ ذخیره شوي نمایش کم کړي، پرته له دې چې د امنیتي تضمینونو له لاسه ورکړي فشار ورکړي. هرڅومره چې د ذخیره شوي ډیټا حجم کوچنی وي ، د اعتبار کونکي نوډ ډیسک ځای اړتیاوې ټیټې وي ، کوم چې د اعتبار کونکي نوډ پیل کول ارزانه کوي ، تاسو ته اجازه درکوي شبکه پراخه کړئ او پدې توګه د شبکې ثبات ډیروي.

پدې پوسټ کې به موږ د همکار لیکوال لخوا د وروستي وړاندیز د زنګ پروټوټایپ پوسټ کړو د بریښنا شبکې کاغذ, Thaddeus Dryja - Utreexo: یو متحرک هش پراساس جمع کونکی د Bitcoin UTXO سیټ لپاره مطلوب، کوم چې د اعتبار کونکي نوډونو لپاره د ډیسک ځای اړتیاو کمولو ته اجازه ورکوي.

څه مشکل ده؟

د Bitcoin د څو کلنو ستونزو څخه یوه د هغې اندازه کول دي. د "ستاسو خپل بانک" مفکوره د شبکې برخه اخیستونکو ته اړتیا لري چې د کارولو لپاره د ټولو فنډونو ریکارډ وساتي. په Bitcoin کې، شته فنډونه د غیر مصرف شوي محصولاتو سیټ په توګه څرګند شوي - یو UTXO-set. پداسې حال کې چې دا په ځانګړي ډول رواني نمایش نه دی، دا د یوې نمایندګۍ په پرتله د پلي کولو فعالیت په برخه کې ګټور دی چې په کې هر "بټوه" د جلا ننوتلو په توګه "توازن" لري، او همدارنګه محرمیت اضافه کوي (د مثال په توګه CoinJoin).

دا مهمه ده چې د معاملو تاریخ (هغه څه چې د بلاکچین په نوم یادیږي) او د سیسټم اوسني حالت ترمنځ توپیر وکړي. د Bitcoin لیږد تاریخ اوس مهال شاوخوا 200 GB ډیسک ځای نیسي، او وده ته دوام ورکوي. په هرصورت، د سیسټم حالت خورا کوچنی دی، د 4 GB په ترتیب کې، او یوازې دا حقیقت په پام کې نیسي چې یو څوک اوس مهال سکې لري. د دې ډیټا حجم هم د وخت په تیریدو سره ډیریږي ، مګر په خورا ورو نرخ کې او ځینې وختونه حتی کمیږي (CDPV وګورئ).

روښانه پیرودونکي (SPVs) د شخصي کیلي پرته بل هیڅ لږترلږه حالت (UTXO-set) ذخیره کولو وړتیا لپاره د سوداګرۍ امنیت تضمین کوي.

UTXO او UTXO-set

UTXO (د نه مصرف شوي لیږد محصول) د نه مصرف شوي لیږد محصول دی ، د هر ساتوشي سفر پای ټکی چې په لیږد کې لیږدول کیږي. نه مصرف شوي محصولات د نویو راکړو ورکړو آخذه کیږي او په دې توګه د UTXO-سیټ څخه مصرف شوي (مصرف) او لرې کیږي.

نوي UTXOs تل د معاملو لخوا رامینځته کیږي:

  • د سکې بیس لیږدونه پرته له معلوماتو څخه: نوي UTXOs رامینځته کړئ کله چې کان کیندونکي سکې صادروي
  • منظم لیږدونه: نوي UTXOs رامینځته کړئ پداسې حال کې چې د موجوده UTXOs یو ټاکلی سیټ مصرف کړئ

د UTXO سره د کار کولو پروسه:
Utreexo: د ډیری UTXO Bitcoin فشارول

والټونه د مصرف (توازن) لپاره د UTXO مقدار پراساس چې دې بټو ته د مصرف لپاره شتون لري شمیري.

د هر اعتباري نوډ، د دوه ګوني مصرف هڅو مخنیوي لپاره، باید د سیټ څارنه وکړي всех UTXO کله چې چک کوي هر یو معاملې هر یو بلاک

نوډ باید منطق ولري:

  • په UTXO-set کې اضافه کول
  • له UTXO-set څخه ړنګول
  • په یوه سیټ کې د یو واحد UTXO شتون چک کول

د یوې سیټ په اړه د زیرمه شوي معلوماتو لپاره د اړتیاو کمولو لارې شتون لري، پداسې حال کې چې د عناصرو اضافه کولو او لرې کولو وړتیا ساتل، په سیټ کې د عنصر شتون چک کول او ثابتول. کریپټوګرافیک جمع کونکي.

د UTXO لپاره بیټرۍ

د ډیری UTXO ذخیره کولو لپاره د بیټرۍ کارولو مفکوره بحث وشو مخکې.

UTXO-سیټ په الوتنه کې جوړ شوی، د ابتدايي بلاک ډاونلوډ (IBD) په جریان کې، په بشپړ او دایمي توګه زیرمه کیږي، پداسې حال کې چې د هغې مینځپانګې د شبکې د هر نوي او سم بلاک څخه د لیږد پروسس کولو وروسته بدلیږي. دا پروسه د نږدې 200 GB بلاک ډیټا ډاونلوډ او د سلګونو ملیون ډیجیټل لاسلیکونو تصدیق کولو ته اړتیا لري. وروسته له دې چې د IBD پروسه بشپړه شي، لاندینۍ کرښه دا ده چې UTXO-set به شاوخوا 4 GB ونیسي.

په هرصورت، د جمع کونکو سره، د فنډونو لپاره د موافقت قواعد د کریپټوګرافیک شواهدو تصدیق او تولید ته کم شوي، او د شته فنډونو تعقیب بار د هغو فنډونو مالک ته لیږدول کیږي، څوک چې د دوی د شتون او مالکیت ثبوت وړاندې کوي.

یو جمع کوونکی د سیټ کمپیکٹ نمایش بلل کیدی شي. د ذخیره شوي نمایش اندازه باید یا هم ثابت وي Utreexo: د ډیری UTXO Bitcoin فشارول، یا د سیټ اصليت او پخپله د عنصر اندازې په پام کې نیولو سره په فرعي ډول لوړ کړئ ، د مثال په توګه Utreexo: د ډیری UTXO Bitcoin فشارول، چیرته چې n د ذخیره شوي سیټ اصليت دی.

په دې حالت کې، جمع کونکی باید اجازه ورکړي چې په سیټ کې د عنصر شاملولو ثبوت تولید کړي (د شاملولو ثبوت) او دا ممکنه کړي چې دا ثبوت په مؤثره توګه تایید کړي.

بیټرۍ ویل کیږي متحرک که تاسو ته اجازه درکوي عناصر اضافه کړئ او له سیټ څخه عناصر لرې کړئ.

د داسې بیټرۍ یوه بیلګه به وي د RSA جمع کونکی د ډسمبر په 2018 کې د Boneh، Bunz، Fisch لخوا وړاندیز شوی. دا ډول جمع کونکی د ذخیره شوي نمایش دوامداره اندازه لري، مګر شتون ته اړتیا لري شریک راز (د باور وړ ترتیب). دا اړتیا د Bitcoin په څیر د بې باوره شبکو لپاره د داسې جمع کونکي پلي کیدو څخه انکار کوي ، ځکه چې د پټ تولید پرمهال د معلوماتو لیک کولی شي برید کونکو ته اجازه ورکړي چې د UTXO شتون غلط ثبوت رامینځته کړي ، د داسې جمع کونکي پراساس د UTXO- سیټ سره نوډونه غلا کوي.

Utreexo

د Utreexo ډیزاین چې د Thaddeus Dryja لخوا وړاندیز شوی د رامینځته کولو امکان برابروي متحرک اکاډمیم پرته باوري ترتیب.

Utreexo د کامل بائنری ځنګل دی د مرکل ونې او په کې وړاندې شوي نظریاتو ته وده ورکول دي د توزیع شوي pki لپاره موثر اسینکرونوس جمع کونکي، د سیټ څخه د عناصرو لرې کولو وړتیا اضافه کول.

د بیټرۍ منطقي جوړښت

د بیټرۍ حجرې د مثالي بائنری ونو په ځنګل کې تنظیم شوي. ونې د قد له مخې ترتیب شوي. دا نمایش د خورا بصری په توګه غوره شوی او تاسو ته اجازه درکوي په بیټرۍ کې د عملیاتو پرمهال د ونو ادغام تصور کړئ.

لیکوال یادونه کوي چې څنګه چې په ځنګل کې ټولې ونې مثالي دي، د دوی لوړوالی د دوه ځواک په توګه څرګند شوی، لکه څنګه چې هر طبیعي شمیره د دوو قوتونو د مجموعې په توګه ښودل کیدی شي. په دې اساس، د پاڼو هر سیټ په بائنری ونو کې ګروپ کیدی شي، او په ټولو حالتونو کې، د نوي عنصر اضافه کول پوهې ته اړتیا لري. یوازې د ذخیره شوي ونو د ریښو نوډونو په اړه.

په دې توګه، د Utreexo جمع کونکي ذخیره شوي نمایش د ریښو نوډونو لیست دی (Merkle root)، او نه د ونو ټول ځنګل.

راځئ چې د ریښو عناصرو لیست په توګه وړاندې کړو Vec<Option<Hash>>. اختیاري ډول Option<Hash> دا په ګوته کوي چې د ریښې عنصر ممکن ورک وي، پدې معنی چې په جمع کونکي کې د مناسب لوړوالي سره هیڅ ونه شتون نلري.

/// SHA-256 хеш
#[derive(Copy, Clone, Hash, Eq, PartialEq)]
pub struct Hash(pub [u8; 32]);

#[derive(Debug, Clone)]
pub struct Utreexo {
    pub roots: Vec<Option<Hash>>,
}

impl Utreexo {
    pub fn new(capacity: usize) -> Self {
        Utreexo {
            roots: vec![None; capacity],
        }
    }
}

د عناصرو اضافه کول

لومړی، راځئ چې فعالیت تشریح کړو parent()، کوم چې د دوه ورکړل شوي عناصرو لپاره اصلي نوډ پیژني.

والدین () فعالیت

له هغه ځایه چې موږ د مرکل ونې کاروو، د هر دوه نوډونو مور یو نوډ دی چې د ماشوم نوډونو د هشونو د ترکیب هش ذخیره کوي:

fn hash(bytes: &[u8]) -> Hash {
    let mut sha = Sha256::new();
    sha.input(bytes);
    let res = sha.result();
    let mut res_bytes = [0u8; 32];
    res_bytes.copy_from_slice(res.as_slice());

    Hash(res_bytes)
}

fn parent(left: &Hash, right: &Hash) -> Hash {
    let concat = left
        .0
        .into_iter()
        .chain(right.0.into_iter())
        .map(|b| *b)
        .collect::<Vec<_>>();

    hash(&concat[..])
}

لیکوال یادونه کوي چې د بریدونو مخنیوي لپاره چې د چارلس بویلګوټ، پییر الین فوک، اډی شامیر، او سیباستین زیمر لخوا بیان شوي.
دوهم پریمیج بریدونه د هیر شوي هش افعال باندې، د دوه هشونو سربیره ، د ونې دننه لوړوالی هم باید په کنټینیشن کې اضافه شي.

لکه څنګه چې تاسو راټولونکي ته عناصر اضافه کوئ، تاسو اړتیا لرئ چې تعقیب کړئ چې کوم ریښې عناصر بدل شوي. د هر عنصر لپاره چې تاسو یې اضافه کوئ د ریښې عناصرو بدلولو لاره تعقیبولو سره، تاسو کولی شئ وروسته د دې عناصرو شتون ثبوت جوړ کړئ.

بدلونونه تعقیب کړئ لکه څنګه چې تاسو یې اضافه کړئ

د شوي بدلونونو تعقیب لپاره، راځئ چې جوړښت اعلان کړو Update، کوم چې به د نوډ بدلونونو په اړه معلومات ذخیره کړي.

#[derive(Debug)]
pub struct Update<'a> {
    pub utreexo: &'a mut Utreexo,
    // ProofStep хранит "соседа" элемента и его положение
    pub updated: HashMap<Hash, ProofStep>,
}

په بیټرۍ کې د عنصر اضافه کولو لپاره، تاسو اړتیا لرئ:

  • د ریښو عناصرو د ټوکرونو لړۍ جوړه کړئ new_roots او هلته موجود ریښې عناصر ځای په ځای کړئ، د هر بالټ لپاره یو:

کوډ

let mut new_roots = Vec::new();

for root in self.roots.iter() {
    let mut vec = Vec::<Hash>::new();
    if let Some(hash) = root {
        vec.push(*hash);
    }

    new_roots.push(vec);
}

  • د اضافه کولو لپاره عناصر ضمیمه کړئ (سری insertions) لومړی کارټ ته new_roots[0]:

Utreexo: د ډیری UTXO Bitcoin فشارول

کوډ

new_roots[0].extend_from_slice(insertions);

  • په لومړي ټوکر کې اضافه شوي توکي د پاتې نورو سره یوځای کړئ:
    • د ټولو کارټونو لپاره چې له یو څخه ډیر توکي لري:
      1. د ټوکر له پای څخه دوه عناصر واخلئ، د دوی مور او پلار حساب کړئ، دواړه عناصر لرې کړئ
      2. په راتلونکي کارټ کې حساب شوي والدین اضافه کړئ

Utreexo: د ډیری UTXO Bitcoin فشارول

کوډ

for i in 0..new_roots.len() {
    while new_roots[i].len() > 1 {
        // Объединяем два элемента в один и удаляем их
        let a = new_roots[i][new_roots[i].len() - 2];
        let b = new_roots[i][new_roots[i].len() - 1];
        new_roots[i].pop();
        new_roots[i].pop();
        let hash = self.parent(&a, &b);

        // Наращиваем количество корзин если требуется
        if new_roots.len() <= i + 1 {
            new_roots.push(vec![]);
        }

        // Помещаем элемент в следующую корзину
        new_roots[i + 1].push(hash);

        // Не забываем отслеживать изменения;
        // это пригодится для генерации доказательства добавления элементов
        updated.insert(a, ProofStep { hash: b, is_left: false });
        updated.insert(b, ProofStep {hash: a, is_left: true });
    }
}

  • د ریښی عناصر له ډنډونو څخه په پایله کې راټولونکي سرې ته واړوئ

کوډ

for (i, bucket) in new_roots.into_iter().enumerate() {
    // Наращиваем аккумулятор если требуется
    if self.roots.len() <= i {
        self.roots.push(None);
    }

    if bucket.is_empty() {
        self.roots[i] = None;
    } else {
        self.roots[i] = Some(bucket[0]);
    }
}

د اضافه عناصرو لپاره د ثبوت رامینځته کول

په بیټرۍ کې د حجرې شاملولو ثبوت (Proof) به د مرکل لارې په توګه خدمت وکړي، چې یو سلسله لري ProofStep. که چیرې لاره هیڅ ځای ته لاړ نشي، نو ثبوت غلط دی.

/// Единичный шаг на пути к элементу в дереве Меркла.
#[derive(Debug, Copy, Clone)]
pub struct ProofStep {
    pub hash: Hash,
    pub is_left: bool,
}

/// Доказательство включения элемента. Содержит сам элемент и путь к нему.
#[derive(Debug, Clone)]
pub struct Proof {
    pub steps: Vec<ProofStep>,
    pub leaf: Hash,
}

مخکې ترلاسه شوي معلومات کارول کله چې یو عنصر اضافه کړئ (ساختمان Update)، تاسو کولی شئ ثبوت پیدا کړئ چې یو عنصر په بیټرۍ کې اضافه شوی. د دې کولو لپاره، موږ د بدلونونو جدول ته ځو او د میرکل په لاره کې هر ګام اضافه کوو، چې وروسته به د ثبوت په توګه کار وکړي:

کوډ

impl<'a> Update<'a> {
    pub fn prove(&self, leaf: &Hash) -> Proof {
        let mut proof = Proof {
            steps: vec![],
            leaf: *leaf,
        };

        let mut item = *leaf;
        while let Some(s) = self.updated.get(&item) {
            proof.steps.push(*s);
            item = parent(&item, &s);
        }

        proof
    }
}

د ثبوت جوړولو پروسه

Utreexo: د ډیری UTXO Bitcoin فشارول

د یو عنصر لپاره ثبوت چک کول

د عنصر د شاملولو ثبوت چک کول د مرکل لار تعقیبولو ته راښکته کیږي تر هغه چې دا د موجوده ریښې عنصر ته وګرځي:

pub fn verify(&self, proof: &Proof) -> bool {
    let n = proof.steps.len();
    if n >= self.roots.len() {
        return false;
    }

    let expected = self.roots[n];
    if let Some(expected) = expected {
        let mut current_parent = proof.leaf;
        for s in proof.steps.iter() {
            current_parent = if s.is_left {
                parent(&s.hash, &current_parent)
            } else {
                parent(&current_parent, &s.hash)
            };
        }

        current_parent == expected
    } else {
        false
    }
}

په لید کې:

د A لپاره د ثبوت چک کولو پروسه

Utreexo: د ډیری UTXO Bitcoin فشارول

د توکو لرې کول

د بیټرۍ څخه د حجرې لرې کولو لپاره، تاسو باید د اعتبار وړ شواهد وړاندې کړئ چې حجره شتون لري. د ثبوت څخه د معلوماتو په کارولو سره ، دا ممکنه ده چې د راټولونکي نوي ریښې عناصر محاسبه کړئ د کوم لپاره چې ورکړل شوی ثبوت به نور ریښتیني نه وي.

الګوریتم په لاندې ډول دی:

  1. د سربيره پردې، موږ د مرکل د ونو سره په مطابقت کې د خالي کڅوړو سيټ تنظيم کوو چې د ټوکر شاخص څخه د دوه ځواک سره مساوي لوړوالی لري.
  2. موږ د مرکل لارې له مرحلو څخه عناصر په ټوکرونو کې دننه کوو؛ د ټوکر شاخص د اوسني مرحلې شمیر سره مساوي دی
  3. موږ د ریښې عنصر لیرې کوو چې د ثبوت څخه لاره ورته ځي
  4. لکه څنګه چې د اضافه کولو سره، موږ د ټوکرونو څخه عناصر په جوړه کې یوځای کولو او د اتحادیې پایله راتلونکي ټوکر ته لیږدولو سره نوي ریښې عناصر محاسبه کوو.

کوډ

fn delete(&self, proof: &Proof, new_roots: &mut Vec<Vec<Hash>>) -> Result<(), ()> {
    if self.roots.len() < proof.steps.len() || self.roots.get(proof.steps.len()).is_none() {
        return Err(());
    }

    let mut height = 0;
    let mut hash = proof.leaf;
    let mut s;

    loop {
        if height < new_roots.len() {
            let (index, ok) = self.find_root(&hash, &new_roots[height]);
            if ok {
                // Remove hash from new_roots
                new_roots[height].remove(index);

                loop {
                    if height >= proof.steps.len() {
                        if !self.roots[height]
                            .and_then(|h| Some(h == hash))
                            .unwrap_or(false)
                        {
                            return Err(());
                        }

                        return Ok(());
                    }

                    s = proof.steps[height];
                    hash = self.parent(&hash, &s);
                    height += 1;
                }
            }
        }

        if height >= proof.steps.len() {
            return Err(());
        }

        while height > new_roots.len() {
            new_roots.push(vec![]);
        }

        s = proof.steps[height];
        new_roots[height].push(s.hash);
        hash = self.parent(&hash, &s);
        height += 1;
    }
}

د عنصر "A" د لرې کولو پروسه:
Utreexo: د ډیری UTXO Bitcoin فشارول

په موجوده شبکه کې ادغام

د وړاندیز شوي جمع کونکي په کارولو سره، نوډونه کولی شي د ټولو UTXO ذخیره کولو لپاره د DB کارولو څخه مخنیوی وکړي پداسې حال کې چې لاهم د UTXO-set بدلولو توان لري. په هرصورت، د شواهدو سره د کار کولو ستونزه رامنځته کیږي.

راځئ چې د اعتبار کونکي نوډ ته زنګ ووهو چې د UTXO جمع کونکي کاروي کمپیکٹ (compact-state node)، او تایید کونکی پرته له جمع کوونکی دی بشپړ (بشپړ نوډ). د نوډونو د دوه ټولګیو شتون په یوه شبکه کې د دوی د ادغام لپاره ستونزه رامینځته کوي، ځکه چې کمپیکٹ نوډونه د UTXOs شتون ثبوت ته اړتیا لري، کوم چې په معاملو کې مصرف شوي، پداسې حال کې چې بشپړ نوډونه نه کوي. که د شبکې ټول نوډونه په یو وخت کې او په همغږي توګه د Utreexo کارولو ته لاړ نشي، نو کمپیکٹ نوډونه به شاته پاتې شي او د Bitcoin شبکې کې به د کار کولو توان ونلري.

په شبکه کې د کمپیکٹ نوډونو ادغام ستونزې حل کولو لپاره ، وړاندیز کیږي چې د نوډونو اضافي ټولګي معرفي شي - پلونه. د برج نوډ یو بشپړ نوډ دی چې د Utreexo بیټرۍ او د بریښنا آن ثبوت هم ذخیره کوي всех UTXO له UTXO-set څخه. پلونه نوي هشونه محاسبه کوي او جمع کونکي او ثبوتونه تازه کوي ځکه چې د معاملو نوي بلاکونه راځي. د جمع کونکي او ثبوتونو ساتل او تازه کول په داسې نوډونو اضافي کمپیوټري بار نه تحمیلوي. پلونه د ډیسک ځای قرباني کوي: د شیانو تنظیم ساتلو ته اړتیا لري Utreexo: د ډیری UTXO Bitcoin فشارول hashes، په پرتله Utreexo: د ډیری UTXO Bitcoin فشارول د کمپیکٹ نوډونو لپاره هشونه، چیرته چې n د UTXO سیټ ځواک دی.

د شبکې جوړښت

Utreexo: د ډیری UTXO Bitcoin فشارول

پلونه دا ممکنه کوي چې په تدریجي ډول د موجوده نوډونو سافټویر بدلولو پرته په شبکه کې کمپیکٹ نوډونه اضافه کړي. بشپړ نوډونه د پخوا په څیر کار کوي، په خپل منځ کې لیږدونه او بلاکونه ویشي. د برج نوډونه بشپړ نوډونه دي چې سربیره پردې د Utreexo بیټرۍ ډیټا او د شاملولو ثبوتونو سیټ ذخیره کوي всех د اوس لپاره UTXO. د برج نوډ خپل ځان داسې اعلان نه کوي، د ټولو بشپړ نوډونو لپاره د بشپړ نوډ او د ټولو کمپیکٹ نوډونو لپاره د کمپیکٹ نوډ په توګه ویاړي. که څه هم پلونه دواړه شبکې له یو بل سره وصلوي، دوی په حقیقت کې یوازې یو لوري ته د نښلولو اړتیا لري: د موجوده بشپړ نوډونو څخه کمپیکٹ نوډونو ته. دا ممکنه ده ځکه چې د راکړې ورکړې بڼه بدلولو ته اړتیا نلري، او د کمپیک نوډونو لپاره د UTXO ثبوتونه رد کیدی شي، نو هر کمپیکٹ نوډ کولی شي د برج نوډونو له ګډون پرته د شبکې ټولو ګډون کونکو ته ورته لیږدونه نشر کړي.

پایلې

موږ د Utreexo بیټرۍ ته وکتل او په Rust کې یې پروټوټایپ پلي کړ. موږ د شبکې جوړښت ته ګورو چې د بیټرۍ پراساس نوډونو ادغام ته اجازه ورکوي. د کمپیکٹ کیچونو ګټه د ذخیره شوي ډیټا اندازه ده، کوم چې په لوګاریتمیک ډول د UTXOs سیټ ځواک پورې اړه لري، کوم چې د ډیسک ځای او د داسې نوډونو لپاره د ذخیره کولو فعالیت اړتیاوې خورا کموي. نیمګړتیا د ثبوتونو لیږدولو لپاره اضافي نوډ ټرافیک دی، مګر د شواهدو راټولولو تخنیکونه (کله چې یو ثبوت د څو عناصرو شتون ثابتوي) او کیشینګ کولی شي د منلو وړ حدونو کې د ټرافیک ساتلو کې مرسته وکړي.

مرجع:

سرچینه: www.habr.com

Add a comment