LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 区块链资产 > 波卡平行链: 攻克区块链不可能三角

波卡平行链: 攻克区块链不可能三角

2019-11-26 PolkaBase 来源:区块链网络

区块链三角

阅读时间:20分钟内含代码

核心问题:

区块链网络的功能一直有不可能三角之说。三角不可兼得:去中心化、可扩展性、安全性。

“区块链三角只能实现其中两个属性” –?以太坊创始人?Vitalik Buterin

图:Web3区块链网络分层架构 (目前已更新到Layer3, Layer4:可拓展合约层)

如何互补:

在Polkadot跨链网络通过分层模型实现多链异构结构实现三者兼备的功能。

Polkadot网络通过改造Layer1底层账本层:主要通过改善共识,增强安全性和去中心化程度;

Layer2的应用层和合约层实现多链并行的功能,在不同的属性上做加强和妥协,整个网络结构上实现三角的互补。

总体上是Polkadot是一个不是百分之百去中心化的多链异构的跨链网络,也在一定妥协的基础上实现安全性、互操作性和可拓展性。

图:举例?-?跨链网络协议layer1、layer2功能

互操作性:

Polkadot跨链网络技术在架构上能够克服克服区块链网络发展的瓶颈。

互操作能力(interoperability)是一个区块链网络满足去中心化、安全性、可扩展性三个属性兼具后可实现的功能。

Polkadot网络协议的核心实现互操作能力(interoperability)。当前不同链的信息和资产的转移只能通过中心化交易所,比如把一个币种换成另一个币种。

在波卡网络中,以中继链为核心互联的不同区块链能实现资产和信息的内部转账。在BTC、以太坊等网络通过桥接链接入后,

例如:把BTC跨以太坊或EOS的交易都可以在Polkadot的客户端钱包中实现转账。

可拓展性:

Polkadot网络的可拓展性体现在能够 横向拓展, 指的是不同链之间大量交易可以平行的进行处理。

Polkadot实现扩展性的关键在于:给平行链设置一个状态机?(state machine)?的网络机制,从而实现开发者能给不同平行链分配任务的功能,

这大大优化了数据的处理速度、每个节点的计算机在运行时所占内存也大大降低。

安全性:

Polkadot在Layer2 Off-Chain层实现了伞型安全架构,伞型体现在有多个校对人节点(collators)围绕一个平行链实行网络监管。少数验证人节点维护网络安全,依据验证人表现的好坏、是否作恶,验证人都会得到奖励和惩罚以此保证维护网络安全的验证人不会做恶。

Polkadot平行链技术实现

图:Polkadot网络角色, 平行链在Polkadot网络中的位置

平行链?(parachain)?是接入Polkadot网络协议的第三方的独立的区块链。

不同平行链连接到中继链实现数据传输和交换。平行链的搭建是Polkadot实现跨链、可扩展、互操作的关键之一。

我们会在下文刨析平行链的代码解释跨链功能的实现过程。

Parachain平行链架构,在真实状态下,并不是像上图那样生物学/工程电路图一般的架构。

开发架构上,平行链由三层语言层写出来的,分别是:

(1)逻辑层 src/lib.rs 用来表达平行链逻辑;

(2)编译层 wasm/lib.rs 当有必要用wrappers编译,例如将高级语言JavaScript中将JS类型转换成Rust,或在Rust中接收wasm类型并将其转为Rust类型;

(3)校对人(collator)层:主要由包括所有客户端上的校对人节点的main.rs文档或者自建模块比如Cargo,一个Rust语言默认的包管理工具、添加依赖项。

Parachain根目录也包含Cargo.toml文档作为编译平行链、运行校对人的依赖,包括运行校对人、标准Polkadot类型等的API:

[package]

name =?"custom_parachain"

version =?"0.1.0"

[dependencies]

polkadot-parachain = { path =?"<path to polkadot/parachain>"?}

polkadot-collator = { path =?"<path to polkadot/collator>"?}

polkadot-primitives = { path =?"<path to polkadot/primitives>"?}

... other libs

搭建Rust环境、Polkadot源码、Cargo.toml工具包如下:

curl?https://sh.rustup.rs -sSf | sh

rustup update nightly

rustup?default?nightly

rustup target add wasm32-unknown-unknown --toolchain nightly #?安装rust环境并使其兼容wasm32工具

cargo install --git https://github.com/alexcrichton/wasm-gc

#?安装完支持Wasm的Rust环境后安装Wasm本体

git clone https://github.com/paritytech/polkadot.git?#?输入源码

cd polkadot

./scripts/build.sh//构建Wasm二进制编译环境

cargo build # Builds all native code

cargo test –all //测试Wasm能不能跑出来

[package]?//在每个文件夹和根目录都可以建立工具包文件

name =?"custom_parachain"

version =?"0.1.0"

[dependencies]

polkadot-parachain = { path =?"<path to polkadot/parachain>"?}

polkadot-collator = { path =?"<path to polkadot/collator>"?}

polkadot-primitives = { path =?"<path to polkadot/primitives>"?}

... other libs

逻辑层?src/lib.r

?首先要创建的是src / lib.rs源。比如添加简单的逻辑以将一些新数据(例如从IoT设备收集的数据)引入链中。

第一行包括在源代码中指定的API,接口和数据类型,我们应该重复使用并实现它们以进行名称匹配:

//启动命令端

#![warn(missing_docs)] //忽略丢失文档

#[macro_use] //首先创建数据源例如从物联网设备中收集的收集导入到平行链中

extern?crate parity_codec_derive;

extern?crate parity_codec;

extern?crate polkadot_parachain as parachain;

extern?crate tiny_keccak;

use parity_codec::{Encode, Decode};

现在,我们将实现主要的平行链数据类型?data type。另外,从某些标准Polkadot数据类型的继承,这里暂时就用预置后的哈希和编码属性。

//Rust语言使用cargo创建工程相对别的语言明显好找启动点,库是lib.rs标记,主程序main.rs标记,波卡链的主程序在polkadot/polkadot/src/main.rs中。

//执行主要的平行链数据类型,使用从标准polkadot数据类型中继承的数据用来hashing和encoding,标准模板如下:

#[derive(Default, Clone, Hash, Eq, PartialEq, Encode, Decode)]

pub?struct?HeadData {

pub block_number: u64,

pub parent_hash: [u8; 32],

pub state_hash: [u8; 32],

}

#[derive(Default, Clone, Encode, Decode)]

pub?struct?BlockData {

pub data_hash: [u8; 32],

pub some_data: IotData,

}

//以下是自定义的数据类型,这里把数据上链

#[derive(Default, Clone, Encode, Decode)]

pub?struct?IotData {

pub iotId: u64,

pub parameter: [char; 20],

pub value: u64,

}

现在,我们继续runtime。这里要实现任何链上逻辑和公共API,能从平行链节点或dApp能访问并遵从该runtime。在本例中,我们将创建一个用于执行自定义逻辑的函数,以及一个用于验证区块和生产新的区块头的函数:

//平行链的运作逻辑构造如下,用来执行所有的链上运作逻辑、和所有能被平行节点和dApps所访问的公开API,构造如下:

pub fn produce_valid_header(

parent_hash: [u8; 32],

parent_head: HeadData,

block_data: &BlockData,

) - Result<HeadData, Debug> {

//所有检测放在如下框中

debug_assert_eq!(parent_hash, parent_head.hash());

let calculated_hash= ::tiny_keccak::keccak256( block_data.some_data[..] )

if?calculated_hash != block_data.data_hash {

return?Err(Debug);

}

let new_state_hash = ::tiny_keccak::keccak256( block_data.encode().as_slice() );

Ok(HeadData {

block_number: parent_head.block_number + 1,

parent_hash,

state_hash: new_state_hash,

})

}

pub fn execute(

parent_hash: [u8; 32],

parent_head: HeadData,

some_data: &SomeData,

) -> Result<HeadData, Debug> {

let block_data: BlockData;

//Custom operations:?将数据整理至区块

match produce_valid_header( parent_hash, parent_head, &block_data ) {

Ok(new_head) => new_head,

Err(_) => Err(Debug),

}

Wasm层:部署验证人节点

接下来我们要码一个接口,用于验证平行链生成的区块?(interface for validating parachain blocks),内含validate函数以及自定义的bug处理模组(a custom error handling function)

首先,我们从平行链runtime中导入必要的模块和数据类型。custom_parachain是我们在上一步中实现的自定义的逻辑函数:

接下来我们执行这个函数 (Polkadot提供了链上数据交互的一些模版)

pub?extern?fn validate(offset: usize, len: usize) -> usize {

//该层主要功能是添加验证平行链区块功能,功能角色被命名为验证人validator。

let params = unsafe { ::parachain::wasm_api::load_params(offset, len) };

let parent_head = HeadData::decode(&mut &params.parent_head[..])

.expect("invalid parent head format.");

let block_data = BlockData::decode(&mut &params.block_data[..])

.expect("invalid block data format.");

let parent_hash = ::tiny_keccak::keccak256( &params.parent_head[..]);

match ::custom_parachain::produce_valid_header( parent_hash, parent_head, &block_data) {

Ok(new_head) => parachain::wasm_api::write_result(

ValidationResult { head_data: new_head.encode() }

),

Err(_) => panic!("validation failure"),

}

}

//可以自行添加一些自己喜欢的bug处理模组

Collator校对人层

这里会码?所有校对人节点的逻辑,从平行链调用逻辑

//从平行链逻辑中调用函数用来打包交易、因为校对人架构也要有时成为验证人在管理网络

use custom_parachain::{HeadData as CustomHead, BlockData as CustomBody, IotData};

use primitives::parachain::{HeadData, BlockData, Id as ParaId, Message, Extrinsic};

use collator::{InvalidHead, ParachainContext, VersionInfo};

创世区块的架构也需要放入校对人节点:

//创世区块架构

const?GENESIS: CustomHead = CustomHead {

block_number: 0,

parent_hash: [0; 32],

state_hash: [some_value],///calculated initial hash value

};

const?GENESIS_BODY: CustomBody = CustomBody {

data_hash: [some_value],

some_data: IotData {

iotId: 0,

parameter: ['n',?'o',?'n',?'e'],

value: 0,

}

};

平行链虽然和一般区块链有点不一样,但也能从一般的区块链数据库、常见的逻辑派生出来。有些有Polkadot模板,同时加入强制性的produce_candidate函数,因为校对人的功能如此。

#[derive(Clone)]

struct CustomContext {

db: Arc<Mutex<HashMap<CustomHead, CustomBody>>>,

}

impl ParachainContext for CustomContext {

fn produce_candidate<I: IntoIterator<Item=(ParaId, Message)>>(

//输入备选节点函数produce_candidate

&self,

last_head: HeadData,

ingress: I,

) -> Result<(BlockData, HeadData, Extrinsic), InvalidHead>

{

//从上一个区块头得到母区块

//从创世区块主体的数据库中得到前一个区块数据

...

//在此处可以输入自设的区块产生逻辑

...

let next_head = ::custom_paracain::execute( parent_head.hash(), parent_head, &next_body );

let encoded_head = HeadData(next_head.encode());

let encoded_body = BlockData(next_body.encode());

//命令符:将区块存储至数据库

db.insert(next_head.clone(), next_body);

Ok((encoded_body, encoded_head, Extrinsic { outgoing_messages: Vec::new() }))

}

}

创世区块所包含的数据值,然后需要建立与校对人的“联系”使得校对人能够挑选最适合网络的区块,将区块推荐给验证人进行验证,进入数据传输的下一步。

fn main() {

let id: ParaId = 100.into();

...

let encoded = GENESIS.encode();

let context = CustomContext {

db: Arc::new(Mutex::new(HashMap::new())),

};

....

let res = ::collator::run_collator(

context,

id,

exit_function,

key_function,

::std::env::args(),

VersionInfo {

......

}

);

...

}

至此,所设置框架的平行链就可以进行编译和部署了。部署及查看平行链可以参考Polkadot wiki,目前大约需要5DOTS可参与测试网,部署后的平行链可以再在Polkascan区块链浏览器中查看。

小结:平行链的了解必读

本文从平行链入手,讲解Polkadot的互操作性、安全性、可扩展化是如何搭建的。

本篇是Polkadot「技术篇」的第三篇了,继上两篇「加强安全保护和拦截网络攻击」和「无需抵押领取免费KSM」后的第三篇代码解读。

未来将继续更新「了解必读」篇,按照上一篇「思维导图」的脉络细讲Polkadot网络架构如何实现网络功能。

编译 / ShawnRingLin

原文:Horbonos, P. (2019). How to Build a Parachain on Polkadot. Apriorit.

—-

编译者/作者:PolkaBase

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...