如何使用Substrate框架来构建自己的区块链
扫描二维码
随时随地手机看文章
arity Substrate是一个区块链开发框架,具有许多很酷的功能,如可升级的区块链,模块化架构,可定制的块执行逻辑和热插拔共识。
Substrate安装
开始使用Substrate的第一步是设置开发环境。Substrate团队创建了一个bash脚本,它安装所有依赖项并编译相关的包作为安装Substrate框架的一部分。
在终端中运行以下命令,将配置Substrate。
curl https://getsubstrate.io -sSf | bash
该命令需要几分钟才能完成(取决于您的硬件),因为它还编译了Substrate框架所需的所有Rust包。
还有一个更快的选项,只安装依赖项,不编译Substrate包。要使用此选项,请运行以下命令。
curl https://getsubstrate.io -sSf | bash -s -- --fast
注意:在该的选项中,不会在全局系统中安装Substrate CLI。
Substrate节点模板
一旦安装脚本完成执行,以及依赖项,您还将在计算机上运行以下几个命令。
其中一个命令是substrate -bode-new命令可帮助您设置模板节点。 将此视为项目框架模板。该命令下载Rust代码库并进行编译。此代码库将设置Substrate运行时所需的所有引导代码打包在一起。
创建节点模板的实例,请在终端中运行以下命令。
substrate-node-new 《project name》 《author name》
第一个参数是区块链项目的名称,第二个(可选)参数是该链作者的名称。
例如:
substrate-node-new substrate-demo demoauthor
一旦该命令完成,它将在substrate demo(或您使用的项目名称)目录中创建以下目录结构。它还将初始化此目录中的Git存储库。
Runtime子目录包含区块链运行时相关逻辑。运行时可以称为区块链的业务逻辑。它进一步分为运行时模块和每个模块包,它们各自的状态(存储)和行为(逻辑)。运行时目录包含运行时模块的文件。
src目录包含低级代码,它将Substrate框架的所有组件集合在一起以执行运行时。
scripts目录包含一个build.sh脚本,该脚本允许我们为Wasm(Web Assembly)环境构建Substrate运行时。
运行Substrate节点
baseline-node-new命令完成执行,它还将编译节点模板的源代码(花费几分钟)。此时,您已经可以启动节点,它将开始生成区块。
要启动Substrate节点,请在node-template目录的上下文中运行以下命令。以下命令将使用dev配置基于node-template启动Substrate节点。实质上,它运行由节点模板代码库编译生成的可执行文件。
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)
如您所见,节点已经开始生成区块。
构建Substrate runtime模块
既然我们都已经使用Substrate设置并且我们的模板节点正在按预期工作,那么让我们为区块链构建一些自定义逻辑。
区块链的业务逻辑驻留在runtime模块中。
假设我们想为令牌传输功能构建一个简单的区块链运行。为实现这一点,我们需要以下内容:
状态:
· 令牌的总供应量
· 帐户和余额映射
行为:
· 令牌初始化(分配给所有者帐户的总供应量)
· 在帐户之间转移令牌
如前所述,Substrate运行时模块将自己的状态和行为打包在一起。我们将使用存储项和函数创建自定义运行时模块。
在node-template目录中,在runtime / src目录中,您将找到两个文件- lib.rs和temaplate.rs。
lib.rs是Runtime的Rust crate root。它导入所有必需的依赖项和类型。它还使用Substrate框架的一些Rust宏部分初始化runtime模块。
template.rs是Substrate runtiem的模板,它包含在节点模板中。它包含一些虚拟状态和行为(在代码注释中有描述),并且本身就是rumtiem模块的功能。
要实现上述令牌功能,我们对template.rs文件进行一些更改。
存储声明
首先,让我们声明令牌功能所需的存储项。在decl_storage! 宏调用,让我们为令牌的总供应和余额映射添加以下两项。
TotalSupply get(total_supply): u64 = 21000000;
BalanceOf get(balance_of): map T::AccountId =》 u64;
在第一行中,我们添加了一个存储项TotalSupply来保存令牌的总数。我们还为此存储项目(21000000)设置了一个值。
在第二行中,我们将另一个存储项创建为StorageMap,并在AccountId和与之关联的令牌余额之间建立映射。我们称这个存储项目为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》》访问模块的存储,以获取和设置这些存储项的值。
注意:从安全性的角度来看,这些函数在检查和验证方面需要更多。但为了简单起见,我们暂时跳过它们。
就是这样;我们现在已经定义了我们的小型区块链运行时的状态和行为。
构建和运行substrate节点
现在让我们通过template.rs文件中的令牌传递函数运行我们刚创建的Substrate运行时。
编译
首先,要编译Wasm环境的运行时,请在repository目录的华宁中运行以下命令。
。/scripts/build.sh
完成上述命令后,运行以下命令为本机环境构建Substrate节点。
cargo build --release
运行节点
在创建节点模板之后,运行该节点与我们之前所做的相同。
。/target/release/substrate-demo --dev
此命令应该再次具有类似的输出,并且该节点应该启动并运行和生成区块。
Substrate节点与用户界面连接
现在我们已经使用令牌传输运行了Substrate节点,让我们将它与UI连接以查看它是否正常工作。
最简单的方法是使用Polkadot Apps Portal。它是一个托管的Web应用程序,主要用于连接到Polkadot网络节点,但它也可以连接到本地Substrate节点。
要使用Polkadot Apps UI进行尝试,请按照以下步骤操作:
· 本地节点运行后,在浏览器中打开以下内容,https://polkadot.js.org/apps/
转到设置页面,然后选择远程节点/端点中的本地节点以连接到输入。单击“保存并重新加载”。
应用程序门户将连接到您的本地Substrate节点,如果您转到Explorer页面,它应该显示生成的块。以下屏幕截图显示了连接了本地节点的Polkadot Apps门户的资源管理器视图。
从UI调用Dispatchable函数
要初始化令牌,请调用Apps门户的Extrinsics页面中模板部分下的init()函数。 请参阅以下屏幕截图以供参考。
如您所见,有一个预先选择的帐户Alice,当单击Submit Transaction按钮时,它将用于签署函数调用。
当此事务在区块中完成时,帐户Alice将根据模块中init()函数中的逻辑具有所有21000000个令牌。
从UI查询存储值
从UI调用init()函数后,帐户Alice应该具有更新的令牌余额21000000.让我们通过检查UI中的存储值来验证。
回想一下上一节,我们使用名为BalanceOf的存储项来存储针对AccountIds的令牌余额。我们来看看Alice的AccountId存储的余额是多少。
您可以使用门户的Chainstate页面来查询存储项目。导航到此页面,从第一个下拉菜单(模块列表)中选择模板,然后从下一个菜单中选择balanceOf(AccountId):u64。从AccountId菜单中,选择Alice。现在点击+按钮。它将显示Alice的令牌余额的更新值(如以下屏幕截图所示)。
就这样。我们构建了一个简单的区块链运行时,并在不到20分钟内将其连接到一个UI。