في مقالة سابقة ، درسنا عدة حالات لاستخدام الحسابات الذكية في الأعمال التجارية - بما في ذلك المزادات وبرامج الولاء.
اليوم سنتحدث عن كيف يمكن للحسابات الذكية والأصول الذكية أن تزيد من شفافية وموثوقية الأدوات المالية مثل الخيارات والعقود الآجلة والسندات.
الخيارالخيار هو عقد تبادل يمنح المشتري حق شراء أصل بسعر معين أو قبل تاريخ معين ، لكنه لا يلزمه بذلك.
قد يكون تمرين الخيار كما يلي:
نحن نستخدم مادة عرض ذكية للخيارات ذاتها كأداة وحساب ذكي للمشارك الذي يعمل كخيارات تبادل وإصدار. يعد عضو البورصة بأنه سيبيع كمية معينة من أصل معين بسعر البيع والسعر بين ارتفاعات انتهاء الصلاحية وكتل انتهاء الصلاحية).
في رمز الأصل الذكي ، نتحقق ببساطة من أنه يتم تداوله فقط بين الارتفاعات المشار إليها ، ولن نتحقق من أي شيء آخر ، وسنترك كل مسؤولية مراقبة القواعد إلى رمز مشارك البورصة.
رمز الأصول الذكية:let expirationStart = 100000 let expirationEnd = 101440 match tx { case some : ExchangeTransaction | TransferTransaction => height > expirationStart && height <= expirationEnd case _ => false }
نحن نفترض أن الإجراءات على النحو التالي: يبيع عضو البورصة خيارات لشراء بعض الأصول ، ويمكن لبقية المشاركين نقل هذه الخيارات أو تداولها. من أجل ممارسة حقه في الشراء ، يجب على المشتري المحتمل أن ينقل العدد المرغوب من الخيارات إلى حساب البائع ، أي مشارك التبادل. ثم يكتب معلومات حول التحويل المكتمل إلى حالة الحساب الخاص بعضو التبادل وعندها فقط سيكون بإمكان ExchangeTransaction الاطلاع على شروط الشراء والبيع المحددة.
في رمز الحساب الذكي ، يجب أن نتأكد من أن أي ExchangeTransaction يمر به لإجراء الشراء والبيع النهائي يفي بالشروط المحددة ، وأن المشارك يشتري بالضبط عدد الوحدات التي أرسلها إلى حساب مشارك التبادل. يجب على المشتري المحتمل أن يرسل DataTransaction الصحيح حول النقل الذي حدث ، بحيث يمكن لعضو التبادل تجنب الإنفاق المزدوج. في DataTransaction ، يضع المشتري على مفتاح مساو لعنوانه قيمة تساوي عدد الخيارات المنقولة إلى حساب عضو البورصة ، أي عدد وحدات الأصول التي يمكنه شرائها.رمز الحساب الذكي: # # sellPrice expirationStart expirationEnd let expirationStart = 100000 let expirationEnd = 101440 let sellPrice = 10000 let amountAsset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf' let priceAsset = base58'9jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf' #ID - let optionsAsset = base58'7jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf' # let this = extract(tx.sender) match tx { case dataTx : DataTransaction => # - (ID ) let units = extract(getInteger(dataTx.data, dataTx.data[0].key)) # - let e = transactionById(dataTx.proofs[2]) # match e { case transferTx : TransferTransaction => #, (transferTx.recipient == this) && #, ID dataTx.data[0].key == toBase58String(transferTx.sender.bytes) && sigVerify(dataTx.bodyBytes, dataTx.proofs[0], transferTx.senderPublicKey) && #, (units == transferTx.amount) && #, - (transferTx.assetId == optionsAsset) case _ => false } && size(dataTx.data) == 1 && !isDefined(getInteger(this, dataTx.data[0].key)) && height > expirationStart && height <= expirationEnd case order : Order => #, let correctAssetPair = order.assetPair.amountAsset == amountAsset && order.assetPair.priceAsset == priceAsset let correctPrice = order.price == sellPrice # - let d = transactionById(order.proofs[2]) match d{ case dataTx : DataTransaction => let buyOrderSender = dataTx.data[0].key toBase58String(order.sender.bytes) == buyOrderSender && order.amount == extract(getInteger(dataTx.data, buyOrderSender)) case _ => false } && order.sender == this && correctAssetPair && correctPrice && height > expirationStart && height <= expirationEnd case _ => false }
العقود الآجلة للحساب الذكيعلى عكس الخيار ، العقود الآجلة (العقد الآجل) ليست حقًا ، ولكن التزام المشتري بشراء أصل بسعر ثابت في نقطة معينة في المستقبل.
بشكل عام ، يشبه تنفيذ العقود المستقبلية تنفيذ خيار ما. هنا ، تعمل الأصول الذكية كعقود مستقبلية.
يجب عليك أيضًا التأكد من توقيع كل من البائع والمشتري على أمر الشراء. العقود المستقبلية هي التزام يجب الوفاء به في أي حال. وهذا يعني أنه إذا رفض البائع أو المشارك التزاماته ، فيمكن لأي مشترك في الشبكة إرسال معاملة ، وبالتالي تنفيذ العقود المستقبلية.
يتحكم البرنامج النصي للأصول الذكية في جميع العقود المستقبلية لأصول النقل و ExchangeTransaction ، ويوافق عليها فقط إذا كان العضو المشترى قد أنشأ طلب شراء مستقبلي للأصول من عضو الصرف.
يجب أن يكون هذا الطلب ساريًا وأن يستوفي الشروط التي صدرت بها العقود المستقبلية. للتحقق من الطلب ، يمكنك إدخال جميع حقوله في حالة حساب المشتري إلى جانب تمثيل البايت للطلب الموقع ، ثم التحقق من الخارج.
في الوقت الحالي ، لا يحتوي RIDE على وظيفة أصلية لتحليل بايتات المعاملة ، ولكنه يتضمن جميع الأدوات اللازمة لتنفيذه. لذلك ، يمكن للمطورين محاولة تطبيق هذه الميزة بمفردهم.
حساب متعدد التوقيع / الضمانيسمح الحساب ذو التوقيع المتعدد للعديد من المستخدمين بالإدارة المشتركة للأصول (على سبيل المثال ، لا يمكن إجراء المعاملات مع الأصول إلا إذا كان لدى ثلاثة من كل أربعة مستخدمين توقيعات). لإنشاء حسابات بتوقيع متعدد بلغة RIDE ، يمكننا استخدام أدلة المعاملة.
يمكن أيضًا استخدام حساب ذو توقيع متعدد لحساب الضمان ، والذي يتم تخزين الأموال فيه حتى تفي أطراف الاتفاقية بالتزاماتها.
let alicePubKey = base58'5AzfA9UfpWVYiwFwvdr77k6LWupSTGLb14b24oVdEpMM' let bobPubKey = base58'2KwU4vzdgPmKyf7q354H9kSyX9NZjNiq4qbnH2wi2VDF' let cooperPubKey = base58'GbrUeGaBfmyFJjSQb9Z8uTCej5GzjXfRDVGJGrmgt5cD' #, let aliceSigned = if(sigVerify(tx.bodyBytes, tx.proofs[0], alicePubKey)) then 1 else 0 let bobSigned = if(sigVerify(tx.bodyBytes, tx.proofs[1], bobPubKey)) then 1 else 0 let cooperSigned = if(sigVerify(tx.bodyBytes, tx.proofs[2], cooperPubKey)) then 1 else 0 # aliceSigned + bobSigned + cooperSigned >= 2
السجل المدار بواسطة الرمز (TCR)على العديد من منصات blockchain ، هناك مشكلة في الأصول السامة. على سبيل المثال ، يمكن لأي عنوان دفع عمولة إنشاء أصل على Waves.
يساعد السجل المدار بواسطة الرمز المميز (TCR) الذي تم إنشاؤه بواسطة حاملي الرمز المميز على حل مشكلة حماية المستخدمين و blockchain من الأصول السامة.
للتصويت على إضافة رمز مميز إلى القائمة ، يقوم صاحب الرهان بعمل رهان مساوٍ لحصته في الرموز المميزة من العدد الإجمالي للمصدر. يتم تضمين رمز مميز في السجل إذا صوت معظم أصحابه لصالحه.
في مثالنا ، نسمح للمستخدم بإضافة الرمز المميز إلى القائمة للنظر (خلال فترة "التحدي") بواسطة مفتاح المفتاح = حالة اسم_الأصل ، فقط إذا كانت القيمة الحالية هي عدد = 0.
أيضًا ، يجب أن يكون لدى المستخدم في المحفظة رصيد غير صفري لهذا الرمز المميز. ثم تأتي فترة التصويت التي يمكن خلالها للمستخدم إجراء تصويت لكل أصل في محفظته ، ولكن مرة واحدة فقط ، مع إعطاء تقييم من 1 إلى 10. يتم تمثيل أصوات المستخدمين بمفاتيح النموذج user_address + الموجودات معرّف.
let asset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf' let addingStartHeight = 1000 let votingStartHeight = 2000 let votingEndHeight = 3000 let this = extract(tx.sender) # let address = addressFromPublicKey(tx.proofs[1]) match tx { case t: DataTransaction => if(height > addingStartHeight) then( if(height < votingStartHeight) then( #adding #, let hasTokens = assetBalance(address, asset) > 0 size(t.data) == 1 #, && !isDefined(getInteger(this, toBase58String(asset))) #, - 0 && extract(getInteger(t.data, toBase58String(asset))) == 0 && hasTokens ) else( if(height < votingEndHeight) then ( #voting # let currentAmount = extract(getInteger(this, toBase58String(asset))) let newAmount = extract(getInteger(t.data, toBase58String(asset))) let betString = toBase58String(address.bytes) + toBase58String(asset) #, let noBetBefore = !isDefined(getInteger(this, betString)) let isBetCorrect = extract(getInteger(t.data, betString)) > 0 && extract(getInteger(t.data, betString)) <= 10 #, let hasTokens = assetBalance(address, asset) > 0 # size(t.data) == 2 && isDefined(getInteger(this, toBase58String(asset))) && newAmount == currentAmount + 1 && noBetBefore && isBetCorrect && hasTokens ) else false ) && sigVerify(tx.bodyBytes, tx.proofs[0], tx.proofs[1]) ) else false case _ => false }
رسوم الاشتراكفي هذا المثال ، سننظر في استخدام الحسابات الذكية لإجراء مدفوعات منتظمة لمنتج أو خدمة على فترات محددة مسبقًا - "رسم شهري".
إذا قدم المستخدم حسابًا ذكيًا (من خلال أدلة المعاملة) مع ID TransferTransaction بالمبلغ المطلوب من الأموال المحولة ، فيمكنه كتابة {key: address، value:
true } في حالة الحساب.
هذا يعني أن المستخدم يؤكد الاشتراك في المنتج أو الخدمة. عند انتهاء الاشتراك ، يمكن لأي مستخدم للشبكة تعيين المفتاح المقابل في الحالة إلى "
خطأ" .
let subscriptionPeriod = 44000 let signature = tx.proofs[0] let pk = tx.proofs[1] let requiredAmount = 100000 let this = extract(tx.sender) match tx { case d: DataTransaction => # let lastPaymentHeight = extract(getInteger(this, d.data[0].key + "_lastPayment")) size(d.data) == 1 && d.data[0].value == "false" && lastPaymentHeight + subscriptionPeriod < height || ( let address = d.data[0].key # - ID, let ttx = transactionById(d.proofs[0]) size(d.data) == 2 && d.data[0].value == "true" && d.data[1].key == address + "_lastPayment" && match ttx { case purchase : TransferTransaction => d.data[1].value == transactionHeightById(purchase.id) && toBase58String(purchase.sender.bytes) == address && purchase.amount == requiredAmount && purchase.recipient == this #, waves && !isDefined(purchase.assetId) case _ => false } ) case _ => false }
التصويتيمكن استخدام الحسابات الذكية لتنفيذ التصويت على blockchain. ومن الأمثلة على ذلك التصويت لأفضل تقرير للسفير في إطار برنامج السفير. يتم استخدام حالة الحساب كمنصة لتسجيل الأصوات لأحد أو لآخر.
في هذا المثال ، يُسمح بالتصويت فقط لأولئك الذين اشتروا الرموز المميزة "للتصويت" الخاصة. يرسل المشارك DataTransaction مقدما مع زوج من (مفتاح ، قيمة) = (purchaseTransactionId ، buyTransactionId). تحديد قيمة مختلفة لهذا المفتاح محظور. باستخدام عنوانك وخيار التصويت ، يمكنك تثبيت DataEntry مرة واحدة فقط. التصويت ممكن فقط خلال الفترة المحددة.
let asset = base58'8jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf' let address = addressFromPublicKey(tx.proofs[1]) let votingStartHeight = 2000 let votingEndHeight = 3000 let this = extract(tx.sender) match tx { case t: DataTransaction => (height > votingStartHeight && height < votingEndHeight) && #, sigVerify(tx.bodyBytes, tx.proofs[0], tx.proofs[1]) && #, if (t.data[0].key == toBase58String(address.bytes)) then ( # let purchaseTx = transactionById(t.proofs[7]) match purchaseTx { case purchase : TransferTransaction => let correctSender = purchase.sender == t.sender let correctAsset = purchase.assetId == asset let correctPrice = purchase.amount == 1 let correctProof = extract(getBinary(this, toBase58String(purchase.id))) == t.id correctSender && correctAsset && correctPrice && correctProof case _ => false } ) else size(t.data) == 1 && !isDefined(getBinary(this, t.data[0].key)) case _ => false }
فاتورة الصرفتعتبر فاتورة الصرف التزامًا مكتوبًا بموجبه يجب على أحد الطرفين أن يدفع للطرف الآخر مبلغًا ثابتًا في وقت الطلب أو في تاريخ محدد مسبقًا.
في مثالنا ، يتم استخدام حساب ذكي ، وهو تاريخ انتهاء الصلاحية الذي يتوافق مع تاريخ دفع الفاتورة.
let expiration = 100000 let amount = 10 let asset = base58'9jfD2JBLe23XtCCSQoTx5eAW5QCU6Mbxi3r78aNQLcNf' let Bob = Address(base58'3NBVqYXrapgJP9atQccdBPAgJPwHDKkh6A8') let Alice = Address(base58'3PNX6XwMeEXaaP1rf5MCk8weYeF7z2vJZBg') match tx { case t: TransferTransaction => (t.assetId == asset)&& (t.amount == amount)&& (t.sender == Bob)&& (t.recipient == Alice)&& (sigVerify(t.bodyBytes, t.proofs[0], t.senderPublicKey))&& (height >= expiration) case _ => false }
إيداعالإيداع - إيداع الأموال في أحد البنوك وفقًا لشروط معينة (الأجل ، النسبة المئوية).
في مثالنا ، يتم تنفيذ وظيفة البنك عن طريق حساب ذكي. بعد عدد معين من القطع ، والتي تتوافق مع مدة الإيداع ، يمكن للمستخدم إرجاع أمواله بنسبة مئوية. يحدد البرنامج النصي ارتفاع الكتلة (finalHeight) ، وبعد ذلك يمكن للمستخدم سحب الأموال من الحساب.
heightUnit - عدد الكتل في وحدة زمنية واحدة (على سبيل المثال ، الشهر ، السنة ، إلخ). أولاً ، نحن نبحث عن إدخال باستخدام زوج (مفتاح ، قيمة) = (initialTransferTransaction ، futureDataTransaction). بعد ذلك ، يجب على المستخدم إرسال TransferTransaction مع المعلومات الصحيحة حول مبلغ الإيداع والفائدة المستحقة لفترة الإيداع. يتم التحقق من هذه المعلومات مقابل TransferTransaction الأصلي الموجود في دليل TransferTransaction الحالي. depositDivisor هو الرقم المقلوب لحصة الإيداع (إذا تم قبول الإيداع بنسبة 10٪ ، تكون حصة الإيداع 0.1 ، ووديع الإيداع = 1 / 0.1 = 10).
let depositDivisor = 10 let heightUnit = 1000 let finalHeight = 100000 let this = extract(tx.sender) match tx { case e : TransferTransaction => # ID let depositHeight = extract(transactionHeightById(e.proofs[7])) # let purchaseTx = transactionById(e.proofs[7]) match purchaseTx { case deposit : TransferTransaction => let correctSender = deposit.sender == e.sender #, + let correctAmount = deposit.amount + deposit.amount / depositDivisor * (height - depositHeight) / heightUnit == e.amount let correctProof = extract(getBinary(this, toBase58String(deposit.id))) == e.id correctSender && correctProof && correctAmount case _ => false } && finalHeight <= height case _ => sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) }
في المقالة الثالثة والأخيرة في هذه السلسلة ، سننظر في المزيد من الخيارات لاستخدام الأصول الذكية ، بما في ذلك تجميد المعاملات وتقييدها لعناوين محددة.