這篇文章主要介紹“Libra的Move交易腳本怎么編寫”,在日常操作中,相信很多人在Libra的Move交易腳本怎么編寫問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對(duì)大家解答”Libra的Move交易腳本怎么編寫”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)是一家專業(yè)提供克山企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站建設(shè)、成都做網(wǎng)站、H5場景定制、小程序制作等業(yè)務(wù)。10年已為克山眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。
Move是一種新的編程語言,旨在為Libra區(qū)塊鏈提供安全且可編程的基礎(chǔ)。 Libra區(qū)塊鏈中的帳戶就是由任意數(shù)量的Move resources和Move modules組成的。 提交給Libra區(qū)塊鏈的每個(gè)交易都使用Move編寫的交易腳本來對(duì)其邏輯進(jìn)行編碼。
交易腳本通過調(diào)用module聲明的procedures來更新區(qū)塊鏈的全局狀態(tài)。
每個(gè)Libra交易都包含一個(gè)Move交易腳本,該腳本對(duì)驗(yàn)證程序代表客戶執(zhí)行的邏輯進(jìn)行編碼(例如,將Libra從A的帳戶轉(zhuǎn)移到B的帳戶)。
通過調(diào)用一個(gè)或多個(gè)Move模塊的procedures,事務(wù)腳本與發(fā)布在Libra區(qū)塊鏈的全局存儲(chǔ)中的Move resources進(jìn)行交互。
事務(wù)腳本并不會(huì)在全局狀態(tài)中存儲(chǔ),并且其他事務(wù)腳本也無法調(diào)用它。 它是一個(gè)一次性程序。
Move modules定義了用來更新Libra區(qū)塊鏈的全局狀態(tài)的規(guī)則。 modules相當(dāng)于其他區(qū)塊鏈中的智能合約。 它聲明了可以在用戶帳戶下發(fā)布的resources類型。 Libra區(qū)塊鏈中的每個(gè)帳戶都是一個(gè)容器,用于容納任意數(shù)量的resources和modules。
module主要用來聲明結(jié)構(gòu)類型(包括資源,這是一種特殊的結(jié)構(gòu))和procedures。
Move module的procedures定義了用于創(chuàng)建,訪問和銷毀其聲明的類型的規(guī)則。
modules是可重用的。 在一個(gè)module中聲明的結(jié)構(gòu)類型可以使用在另一個(gè)module中聲明的結(jié)構(gòu)類型,并且在一個(gè)module中聲明的可以procedure調(diào)用在另一個(gè)module中聲明的public procedures。 一個(gè)module可以調(diào)用在其他Move module中聲明的procedures。 事務(wù)腳本可以調(diào)用已發(fā)布module的任何public procedures。
最后,Libra用戶將能夠使用自己的帳戶發(fā)布modules。
Move的主要功能是能夠定義自定義資源類型。 資源類型主要對(duì)數(shù)字資產(chǎn)進(jìn)行編碼。
資源在Libra中隨處可見。 它們可以存儲(chǔ)為數(shù)據(jù)結(jié)構(gòu),可以作為參數(shù)傳遞給過程,可以從過程中返回,等等。
Move type system為資源提供了特殊的安全保證。 Move resources永遠(yuǎn)不能被復(fù)制,重用或丟棄。 資源類型只能由定義該類型的模塊創(chuàng)建或銷毀。這是由Move虛擬機(jī)通過字節(jié)碼驗(yàn)證來強(qiáng)制進(jìn)行保證的。 Move虛擬機(jī)將拒絕運(yùn)行尚未通過字節(jié)碼驗(yàn)證程序的代碼。
Libra貨幣是通過LibraCoin.T的資源類型來實(shí)現(xiàn)的。 和其他的資源一樣,LibraCoin.T也是一種資源。
本節(jié)我會(huì)介紹怎么使用Move IR來編寫事務(wù)腳本和模塊。IR是即將推出的Move源語言的預(yù)覽版本(不穩(wěn)定)。 Move IR是Move字節(jié)碼上的一個(gè)薄語法層,用于測試字節(jié)碼驗(yàn)證程序和虛擬機(jī),它對(duì)開發(fā)人員并不特別友好。 它足夠高,可以編寫人類可讀的代碼,但是也足夠低,可以直接編譯為Move字節(jié)碼。
用戶通過交易腳本來請(qǐng)求對(duì)Libra區(qū)塊鏈的全局存儲(chǔ)進(jìn)行更新。幾乎所有事務(wù)腳本中都會(huì)出現(xiàn)兩個(gè)重要資源:LibraAccount.T和LibraCoin.T資源類型。 LibraAccount是module的名稱,而T是該module聲明的資源的名稱。這是Move中的通用命名約定。module聲明的“主要”類型通常稱為T。
當(dāng)我們說用戶“在Libra區(qū)塊鏈上的地址0xff擁有一個(gè)帳戶”時(shí),我們的意思是地址0xff擁有LibraAccount.T資源的實(shí)例。每個(gè)非空地址都有一個(gè)LibraAccount.T資源。此資源存儲(chǔ)帳戶數(shù)據(jù),例如序列號(hào),身份驗(yàn)證密鑰和余額。要與帳戶進(jìn)行交互的Libra系統(tǒng)的任何部分都必須通過從LibraAccount.T資源中讀取數(shù)據(jù)或調(diào)用LibraAccount module的procedures來進(jìn)行此操作。
帳戶余額是LibraCoin.T類型的資源。這是Libra貨幣的類型。與任何其他Move資源一樣,此類型在語言上是一等公民。
LibraCoin.T類型的資源可以存儲(chǔ)在程序變量中,在過程之間傳遞,等等。
現(xiàn)在讓我們看看程序員如何在事務(wù)腳本中與這些模塊和資源進(jìn)行交互。
// Simple peer-peer payment example.// Use LibraAccount module published on the blockchain at account address// 0x0...0 (with 64 zeroes). 0x0 is shorthand that the IR pads out to// 256 bits (64 digits) by adding leading zeroes.import 0x0.LibraAccount;import 0x0.LibraCoin;main(payee: address, amount: u64) { // The bytecode (and consequently, the IR) has typed locals. The scope of // each local is the entire procedure. All local variable declarations must // be at the beginning of the procedure. Declaration and initialization of // variables are separate operations, but the bytecode verifier will prevent // any attempt to use an uninitialized variable. let coin: LibraCoin.T; // Acquire a LibraCoin.T resource with value `amount` from the sender's // account. This will fail if the sender's balance is less than `amount`. coin = LibraAccount.withdraw_from_sender(move(amount)); // Move the LibraCoin.T resource into the account of `payee`. If there is no // account at the address `payee`, this step will fail LibraAccount.deposit(move(payee), move(coin)); // Every procedure must end in a `return`. The IR compiler is very literal: // it directly translates the source it is given. It will not do fancy // things like inserting missing `return`s. return;}
此交易腳本有一個(gè)不幸的問題-如果收款人下沒有帳戶,它將失敗。 我們將通過修改腳本為收款人創(chuàng)建帳戶(如果尚不存在)來解決此問題。
// A small variant of the peer-peer payment example that creates a fresh// account if one does not already exist.import 0x0.LibraAccount;import 0x0.LibraCoin;main(payee: address, amount: u64) { let coin: LibraCoin.T; let account_exists: bool; // Acquire a LibraCoin.T resource with value `amount` from the sender's // account. This will fail if the sender's balance is less than `amount`. coin = LibraAccount.withdraw_from_sender(move(amount)); account_exists = LibraAccount.exists(copy(payee)); if (!move(account_exists)) {// Creates a fresh account at the address `payee` by publishing a// LibraAccount.T resource under this address. If theres is already a// LibraAccount.T resource under the address, this will fail.create_account(copy(payee)); } LibraAccount.deposit(move(payee), move(coin)); return;}
讓我們看一個(gè)更復(fù)雜的例子。 在此示例中,我們將使用交易腳本向多個(gè)收件人付款,而不僅僅是一個(gè)。
// Multiple payee example. This is written in a slightly verbose way to// emphasize the ability to split a `LibraCoin.T` resource. The more concise// way would be to use multiple calls to `LibraAccount.withdraw_from_sender`.import 0x0.LibraAccount;import 0x0.LibraCoin;main(payee1: address, amount1: u64, payee2: address, amount2: u64) { let coin1: LibraCoin.T; let coin2: LibraCoin.T; let total: u64; total = move(amount1) + copy(amount2); coin1 = LibraAccount.withdraw_from_sender(move(total)); // This mutates `coin1`, which now has value `amount1`. // `coin2` has value `amount2`. coin2 = LibraCoin.withdraw(&mut coin1, move(amount2)); // Perform the payments LibraAccount.deposit(move(payee1), move(coin1)); LibraAccount.deposit(move(payee2), move(coin2)); return;}
好了,這就是簡單的交易腳本,雖然我們不了解Move IR的語法,但是直接看內(nèi)容應(yīng)該就很容易明白這個(gè)腳本到底在做什么了。
上面的交易腳本使用了現(xiàn)有的LibraAccount和LibraCoin modules,那么我們怎么編寫自己的Move modules呢?
考慮這種情況:B將來會(huì)在地址a創(chuàng)建一個(gè)帳戶。 A想為B“專款”一些資金,以便他一旦創(chuàng)建就可以將其存入他的帳戶。 但是,如果B從未創(chuàng)建該帳戶,她還希望能夠自己收回資金。
為了解決A的這個(gè)問題,我們將編寫一個(gè)模塊EarmarkedLibraCoin:
聲明一個(gè)新的資源類型EarmarkedLibraCoin.T,該資源類型包裝了Libra coin和收件人地址。
允許A創(chuàng)建此類類型并將其發(fā)布到她的帳戶下(創(chuàng)建過程)。
允許B聲明資源(claim_for_recipient過程)。
允許擁有EarmarkedLibraCoin.T的任何人銷毀它并獲得相應(yīng)的coin(拆包程序)。
// A module for earmarking a coin for a specific recipientmodule EarmarkedLibraCoin { import 0x0.LibraCoin; // A wrapper containing a Libra coin and the address of the recipient the // coin is earmarked for. resource T {coin: LibraCoin.T,recipient: address } // Create a new earmarked coin with the given `recipient`. // Publish the coin under the transaction sender's account address. public create(coin: LibraCoin.T, recipient: address) {let t: Self.T;// Construct or "pack" a new resource of type T. Only procedures of the// `EarmarkedLibraCoin` module can create an `EarmarkedLibraCoin.T`.t = T { coin: move(coin), recipient: move(recipient),};// Publish the earmarked coin under the transaction sender's account// address. Each account can contain at most one resource of a given type;// this call will fail if the sender already has a resource of this type.move_to_sender(move(t));return; } // Allow the transaction sender to claim a coin that was earmarked for her. public claim_for_recipient(earmarked_coin_address: address): Self.T acquires T {let t: Self.T;let t_ref: &Self.T;let sender: address;// Remove the earmarked coin resource published under `earmarked_coin_address`.// If there is no resource of type T published under the address, this will fail.t = move_from (move(earmarked_coin_address));t_ref = &t;// This is a builtin that returns the address of the transaction sender.sender = get_txn_sender();// Ensure that the transaction sender is the recipient. If this assertion// fails, the transaction will fail and none of its effects (e.g.,// removing the earmarked coin) will be committed. 99 is an error code// that will be emitted in the transaction output if the assertion fails.assert(*(&move(t_ref).recipient) == move(sender), 99);return move(t); } // Allow the creator of the earmarked coin to reclaim it. public claim_for_creator(): Self.T acquires T {let t: Self.T;let sender: address;sender = get_txn_sender();// This will fail if no resource of type T under the sender's address.t = move_from (move(sender));return move(t); } // Extract the Libra coin from its wrapper and return it to the caller. public unwrap(t: Self.T): LibraCoin.T {let coin: LibraCoin.T;let recipient: address;// This "unpacks" a resource type by destroying the outer resource, but// returning its contents. Only the module that declares a resource type// can unpack it.T { coin, recipient } = move(t);return move(coin); }}
A可以通過創(chuàng)建交易腳本來為B創(chuàng)建專用coin,該交易腳本調(diào)用B地址a上的create和她擁有的LibraCoin.T。 創(chuàng)建a之后,B可以通過發(fā)送來自a的交易來claim coin。 這將調(diào)用claim_for_recipient,將結(jié)果傳遞給unwrap,并在他希望的任何地方存儲(chǔ)返回的LibraCoin。
如果B花費(fèi)太長時(shí)間在a帳戶下創(chuàng)建帳戶,而A想要收回其資金,則可以通過使用Claim_for_creator然后取消unwrap來做到這一點(diǎn)。
到此,關(guān)于“Libra的Move交易腳本怎么編寫”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!