溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Libra的Move交易腳本怎么編寫

發(fā)布時(shí)間:2022-01-15 10:52:11 來源:億速云 閱讀:112 作者:iii 欄目:互聯(lián)網(wǎng)科技

這篇文章主要介紹“Libra的Move交易腳本怎么編寫”,在日常操作中,相信很多人在Libra的Move交易腳本怎么編寫問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Libra的Move交易腳本怎么編寫”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

Move語言

Move是一種新的編程語言,旨在為Libra區(qū)塊鏈提供安全且可編程的基礎(chǔ)。 Libra區(qū)塊鏈中的帳戶就是由任意數(shù)量的Move resources和Move modules組成的。 提交給Libra區(qū)塊鏈的每個(gè)交易都使用Move編寫的交易腳本來對其邏輯進(jìn)行編碼。

交易腳本通過調(diào)用module聲明的procedures來更新區(qū)塊鏈的全局狀態(tài)。

Move的核心概念

Move交易腳本

每個(gè)Libra交易都包含一個(gè)Move交易腳本,該腳本對驗(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

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 resources

Move的主要功能是能夠定義自定義資源類型。 資源類型主要對數(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也是一種資源。

寫一個(gè)Move程序

本節(jié)我會(huì)介紹怎么使用Move IR來編寫事務(wù)腳本和模塊。IR是即將推出的Move源語言的預(yù)覽版本(不穩(wěn)定)。 Move IR是Move字節(jié)碼上的一個(gè)薄語法層,用于測試字節(jié)碼驗(yàn)證程序和虛擬機(jī),它對開發(fā)人員并不特別友好。 它足夠高,可以編寫人類可讀的代碼,但是也足夠低,可以直接編譯為Move字節(jié)碼。

編寫交易腳本

用戶通過交易腳本來請求對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è)腳本到底在做什么了。

編寫自己的Modules

上面的交易腳本使用了現(xiàn)有的LibraAccount和LibraCoin modules,那么我們怎么編寫自己的Move modules呢?

考慮這種情況:B將來會(huì)在地址a創(chuàng)建一個(gè)帳戶。 A想為B“??睢币恍┵Y金,以便他一旦創(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<T>(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<T>(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<T>(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í),請繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI