arity Substrate是一個區(qū)塊鏈開發(fā)框架,具有許多很酷的功能,如可升級的區(qū)塊鏈,模塊化架構,可定制的塊執(zhí)行邏輯和熱插拔共識。
Substrate安裝
開始使用Substrate的第一步是設置開發(fā)環(huán)境。Substrate團隊創(chuàng)建了一個bash腳本,它安裝所有依賴項并編譯相關的包作為安裝Substrate框架的一部分。
在終端中運行以下命令,將配置Substrate。
curl https://getsubstrate.io -sSf | bash
該命令需要幾分鐘才能完成(取決于您的硬件),因為它還編譯了Substrate框架所需的所有Rust包。
還有一個更快的選項,只安裝依賴項,不編譯Substrate包。要使用此選項,請運行以下命令。
curl https://getsubstrate.io -sSf | bash -s -- --fast
注意:在該的選項中,不會在全局系統(tǒng)中安裝Substrate CLI。
Substrate節(jié)點模板
一旦安裝腳本完成執(zhí)行,以及依賴項,您還將在計算機上運行以下幾個命令。
其中一個命令是substrate -bode-new命令可幫助您設置模板節(jié)點。 將此視為項目框架模板。該命令下載Rust代碼庫并進行編譯。此代碼庫將設置Substrate運行時所需的所有引導代碼打包在一起。
創(chuàng)建節(jié)點模板的實例,請在終端中運行以下命令。
substrate-node-new 《project name》 《author name》
第一個參數是區(qū)塊鏈項目的名稱,第二個(可選)參數是該鏈作者的名稱。
例如:
substrate-node-new substrate-demo demoauthor
一旦該命令完成,它將在substrate demo(或您使用的項目名稱)目錄中創(chuàng)建以下目錄結構。它還將初始化此目錄中的Git存儲庫。
Runtime子目錄包含區(qū)塊鏈運行時相關邏輯。運行時可以稱為區(qū)塊鏈的業(yè)務邏輯。它進一步分為運行時模塊和每個模塊包,它們各自的狀態(tài)(存儲)和行為(邏輯)。運行時目錄包含運行時模塊的文件。
src目錄包含低級代碼,它將Substrate框架的所有組件集合在一起以執(zhí)行運行時。
scripts目錄包含一個build.sh腳本,該腳本允許我們?yōu)閃asm(Web Assembly)環(huán)境構建Substrate運行時。
運行Substrate節(jié)點
baseline-node-new命令完成執(zhí)行,它還將編譯節(jié)點模板的源代碼(花費幾分鐘)。此時,您已經可以啟動節(jié)點,它將開始生成區(qū)塊。
要啟動Substrate節(jié)點,請在node-template目錄的上下文中運行以下命令。以下命令將使用dev配置基于node-template啟動Substrate節(jié)點。實質上,它運行由節(jié)點模板代碼庫編譯生成的可執(zhí)行文件。
cd substrate-demo // in case you haven‘t done this already
。/target/release/substrate-demo --dev
該命令將生成類似于以下內容的輸出。
2019-07-25 17:28:31 Substrate Node
2019-07-25 17:28:31 version 1.0.0-x86_64-linux-gnu
2019-07-25 17:28:31 by demoauthor, 2017, 2018
2019-07-25 17:28:31 Chain specification: Development
2019-07-25 17:28:31 Node name: adorable-wind-3578
2019-07-25 17:28:31 Roles: AUTHORITY
2019-07-25 17:28:31 Initializing Genesis block/state (state: 0x4397…ab51, header-hash: 0x0353…30ef)
2019-07-25 17:28:31 Loaded block-time = 10 seconds from genesis on first-launch
2019-07-25 17:28:31 Best block: #0
2019-07-25 17:28:31 Local node address is: /ip4/0.0.0.0/tcp/30333/p2p/QmYsPTbsxQiKV8Dk3rWL19xFXxfpt2NrzFRd2P63AjRM3o
2019-07-25 17:28:31 Listening for new connections on 127.0.0.1:9944.
2019-07-25 17:28:31 Using authority key 5FA9nQDVg267DEd8m1ZypXLBnvN7SFxYwV7ndqSYGiN9TmTd
2019-07-25 17:28:40 Starting consensus session on top of parent 0x03534673f220e0514d5324acd179438094e05f4c2419f33226c42e33f5cf30ef
2019-07-25 17:28:40 Prepared block for proposing at 1 [hash: 0xdc6de1c9b04607fe51bf4abed8cfdbd6313a74e9eeda78e3db4f6d2b60e69903; parent_hash: 0x0353…30ef; extrinsics: [0x0421…0149]]
2019-07-25 17:28:40 Pre-sealed block for proposal at 1. Hash now 0x1e5375649660d9e8b8e41fde74c861185a1e55153285e4332111dd0aa240684a, previously 0xdc6de1c9b04607fe51bf4abed8cfdbd6313a74e9eeda78e3db4f6d2b60e69903.
2019-07-25 17:28:40 Imported #1 (0x1e53…684a)
如您所見,節(jié)點已經開始生成區(qū)塊。
構建Substrate runtime模塊
既然我們都已經使用Substrate設置并且我們的模板節(jié)點正在按預期工作,那么讓我們?yōu)閰^(qū)塊鏈構建一些自定義邏輯。
區(qū)塊鏈的業(yè)務邏輯駐留在runtime模塊中。
假設我們想為令牌傳輸功能構建一個簡單的區(qū)塊鏈運行。為實現這一點,我們需要以下內容:
狀態(tài):
· 令牌的總供應量
· 帳戶和余額映射
行為:
· 令牌初始化(分配給所有者帳戶的總供應量)
· 在帳戶之間轉移令牌
如前所述,Substrate運行時模塊將自己的狀態(tài)和行為打包在一起。我們將使用存儲項和函數創(chuàng)建自定義運行時模塊。
在node-template目錄中,在runtime / src目錄中,您將找到兩個文件- lib.rs和temaplate.rs。
lib.rs是Runtime的Rust crate root。它導入所有必需的依賴項和類型。它還使用Substrate框架的一些Rust宏部分初始化runtime模塊。
template.rs是Substrate runtiem的模板,它包含在節(jié)點模板中。它包含一些虛擬狀態(tài)和行為(在代碼注釋中有描述),并且本身就是rumtiem模塊的功能。
要實現上述令牌功能,我們對template.rs文件進行一些更改。
存儲聲明
首先,讓我們聲明令牌功能所需的存儲項。在decl_storage! 宏調用,讓我們?yōu)榱钆频目偣陀囝~映射添加以下兩項。
TotalSupply get(total_supply): u64 = 21000000;
BalanceOf get(balance_of): map T::AccountId =》 u64;
在第一行中,我們添加了一個存儲項TotalSupply來保存令牌的總數。我們還為此存儲項目(21000000)設置了一個值。
在第二行中,我們將另一個存儲項創(chuàng)建為StorageMap,并在AccountId和與之關聯(lián)的令牌余額之間建立映射。我們稱這個存儲項目為BalanceOf。
此模塊的完整存儲聲明代碼如下所示。(注意:我們刪除了模板模塊附帶的虛擬存儲項。)
// storage for this runtime module
decl_storage! {
trait Store for Module《T: Trait》 as Template {
TotalSupply get(total_supply): u64 = 21000000;
BalanceOf get(balance_of): map T::AccountId =》 u64;
}
}
實現runtime邏輯
現在我們已經為Substrate模塊定義了存儲,讓我們編寫一些代碼來操作這些存儲項。
在Substrate模塊中,使用decl_module!宏 ,定義公共可調度函數 我們有兩個函數可以在我們的模塊中實現簡單的令牌傳輸功能。這些是令牌和傳遞函數的初始化。
在下面的代碼片段中,這兩個可調度函數 - init和transfer在decl_module! 宏中定義。
decl_module! {
pub struct Module《T: Trait》 for enum Call where origin: T::Origin {
// initialize the token
// transfers the total_supply amout to the caller
fn init(origin) -》 Result {
let sender = ensure_signed(origin)?;
《BalanceOf《T》》::insert(sender, Self::total_supply());
Ok(())
}
// transfer tokens from one account to another
fn transfer(_origin, to: T::AccountId, value: u64) -》 Result {
let sender = ensure_signed(_origin)?;
let sender_balance = Self::balance_of(sender.clone());
ensure!(sender_balance 》= value, “Not enough balance.”);
let updated_from_balance =
sender_balance.checked_sub(value)
.ok_or(“overflow in calculating balance”)?;
let receiver_balance = Self::balance_of(to.clone());
let updated_to_balance = receiver_balance.checked_add(value)
.ok_or(“overflow in calculating balance”)?;
// reduce sender’s balance
《BalanceOf《T》》::insert(sender, updated_from_balance);
// increase receiver‘s balance
《BalanceOf《T》》::insert(to.clone(), updated_to_balance);
Ok(())
}
}
}
請注意,我們如何使用self::total_supply()和《balanceof《t》》訪問模塊的存儲,以獲取和設置這些存儲項的值。
注意:從安全性的角度來看,這些函數在檢查和驗證方面需要更多。但為了簡單起見,我們暫時跳過它們。
就是這樣;我們現在已經定義了我們的小型區(qū)塊鏈運行時的狀態(tài)和行為。
構建和運行substrate節(jié)點
現在讓我們通過template.rs文件中的令牌傳遞函數運行我們剛創(chuàng)建的Substrate運行時。
編譯
首先,要編譯Wasm環(huán)境的運行時,請在repository目錄的華寧中運行以下命令。
。/scripts/build.sh
完成上述命令后,運行以下命令為本機環(huán)境構建Substrate節(jié)點。
cargo build --release
運行節(jié)點
在創(chuàng)建節(jié)點模板之后,運行該節(jié)點與我們之前所做的相同。
。/target/release/substrate-demo --dev
此命令應該再次具有類似的輸出,并且該節(jié)點應該啟動并運行和生成區(qū)塊。
Substrate節(jié)點與用戶界面連接
現在我們已經使用令牌傳輸運行了Substrate節(jié)點,讓我們將它與UI連接以查看它是否正常工作。
最簡單的方法是使用Polkadot Apps Portal。它是一個托管的Web應用程序,主要用于連接到Polkadot網絡節(jié)點,但它也可以連接到本地Substrate節(jié)點。
要使用Polkadot Apps UI進行嘗試,請按照以下步驟操作:
· 本地節(jié)點運行后,在瀏覽器中打開以下內容,https://polkadot.js.org/apps/
轉到設置頁面,然后選擇遠程節(jié)點/端點中的本地節(jié)點以連接到輸入。單擊“保存并重新加載”。
應用程序門戶將連接到您的本地Substrate節(jié)點,如果您轉到Explorer頁面,它應該顯示生成的塊。以下屏幕截圖顯示了連接了本地節(jié)點的Polkadot Apps門戶的資源管理器視圖。
從UI調用Dispatchable函數
要初始化令牌,請調用Apps門戶的Extrinsics頁面中模板部分下的init()函數。 請參閱以下屏幕截圖以供參考。
如您所見,有一個預先選擇的帳戶Alice,當單擊Submit Transaction按鈕時,它將用于簽署函數調用。
當此事務在區(qū)塊中完成時,帳戶Alice將根據模塊中init()函數中的邏輯具有所有21000000個令牌。
從UI查詢存儲值
從UI調用init()函數后,帳戶Alice應該具有更新的令牌余額21000000.讓我們通過檢查UI中的存儲值來驗證。
回想一下上一節(jié),我們使用名為BalanceOf的存儲項來存儲針對AccountIds的令牌余額。我們來看看Alice的AccountId存儲的余額是多少。
您可以使用門戶的Chainstate頁面來查詢存儲項目。導航到此頁面,從第一個下拉菜單(模塊列表)中選擇模板,然后從下一個菜單中選擇balanceOf(AccountId):u64。從AccountId菜單中,選擇Alice。現在點擊+按鈕。它將顯示Alice的令牌余額的更新值(如以下屏幕截圖所示)。
就這樣。我們構建了一個簡單的區(qū)塊鏈運行時,并在不到20分鐘內將其連接到一個UI。
評論
查看更多