当前位置:首页区块链在运行时的衬底中添加契约模块

在运行时的衬底中添加契约模块

在运行时的衬底中添加契约模块

增加托盘

底层节点模板[1]提供了最小的运行时,您可以使用它来快速构建自定义区块链。但是,为了使其最小化,它不包括框架[2]中的大多数托盘。

本指南将向您展示如何将契约面板[3]添加到运行时,以便您的区块链支持Wasm智能契约。您可以以类似的模式将其他框架托盘添加到运行时中,但需要注意的是,每个托盘都具有使用它所需的一组稍微不同的特定配置。

安装节点模板

当您完成创建第一个基底链[4]的教程时,您应该已经编译了2.0.0-alpha。衬底节点模板[5]的8位在您的计算机上。如果没有,请先完成教程。

如果您是一位经验丰富的开发人员,并且希望跳过本教程,那么建议您按照readme中的描述安装节点模板。

文档结构

现在,我们将修改substrate-node-template以包含契约面板。

选择您喜欢的代码编辑器并打开substrate-node-template。我们将编辑两个文件:runtime/ SRC /lib。rs和运行时/ load.toml。

衬底-节点模板|+—运行时|| |+—货物。Toml  lt;——这个文件|| | +——build中的一个更改。rs | | | + - SRC | | | +——自由。大多数的改变这个文件| | + +——托盘| +脚本——节点| +……

进口托盘板条箱

要添加契约模块,需要做的第一件事是将palm-contract板条箱导入到加载中。运行时的toml文件。如果你想要在货物参考中找到一个合适的介绍,你应该参考它的官方文档[6]。

打开substrate – node – the template/runtime/Cargo toml,你会看到runtime有一个所有依赖项的列表。例如,它依靠平衡托盘[7]:

运行时/货物。Toml

(依赖关系。balance] git =' https://github.com/paritytech/substrate.git'默认-功能= falsepackage ='托盘- balance '标签=' 8 '2.0.0 - alpha。箱功能

在导入模块板条箱时要注意的一件事是确保板条箱功能设置正确。在上面的代码片段中,您会注意到我们设置了DeFiault_features = false。如果你仔细观察容器。toml文件,你会发现这样的东西:

运行时/货物。Toml

[功能]默认= [' STD'] STD = [' codec/STD ', 'client/STD', 'sp - STD/STD', 'sp - IO/STD', 'balance /STD', 'frame - support/STD, # - "]

第二行将运行时板条箱的默认函数定义为STD。可以想象,每个板条箱都有一个类似的配置,它定义了这个板条箱的默认函数。您的功能将决定应该在下游依赖项上使用哪些功能。例如,上面的代码片段应该是:

这个底层运行时的默认函数是STD。如果您为运行时启用了STD,那么par- scale-codec、原语、客户端和所有其他列出的依赖项也应该使用它们的STD功能。

这对于使底层运行时能够编译到本地二进制文件(支持Rust ‘STD'[8])和Wasm二进制文件(不支持’no_std'[9])非常有用。

要查看这些函数在运行时代码中是如何实际使用的,请打开项目文件:

运行时/ SRC / lib。Rs

/ / !TheSubstrateNodeTemplateruntime。这可以成为堆' # no_std ',准备forwasm。# ![cfg_attr (not (feature = "STD"), no_std)] / / ' construct_runtime!“doesaLootofrecursionandrequiresustoincreasETHelimitto256。# ![recursion_limit = "256"] / /让wasmbinaryaailable。# / CFG (feature = "STD")包括!(concat !(en !(" OUT_DIR "), "/ wasm_binary。Rs”));/ / - - - - - -”

如您所见,在文件的顶部,我们定义在不使用STD功能时将使用no_std。

在接下来的代码行中,您将看到#[CFG (feature = “STD “)]位于wasm_bind之上。rs导入,这是一个要求仅在启用STD时导入WASM二进制文件的标志。引进合同托盘板条箱

好了,现在我们知道了板条箱的基本功能,我们可以实际导入合同托盘。作为框架中最复杂的模块,它很好地说明了添加其他模块时可能涉及的一些棘手问题。

首先,我们将通过简单地复制现有模块并更改值来添加一个新的依赖项。因此,根据上述差额进口,进口合同将类似于:

运行时/货物。Toml

(依赖关系。合同]git =' https://github.com/paritytech/substrate.git'默认-功能= falsepackage ='托盘-合同'标签=' 8 '2.0.0 - alpha。(依赖关系。合同-原语]git =' https://github.com/paritytech/substrate.git'默认-功能= falsepackage ='托盘-合同-原语'标签=' 8 '2.0.0 - alpha。

与其他模块一样,合同托盘具有STD功能。当运行时构建它自己的STD功能时,我们应该构建它的STD功能。向运行时STD功能添加以下两行。

运行时/货物。Toml

[features]DeFiault = [" STD "] STD =[#——snip——'contracts/ STD ', 'contract -primities/ STD ', #——snip——]

如果忘记预先设置功能,在生成本机二进制文件时会出现以下错误:

错误:[E0425] cannotfindfunction ' memory_teardown ' inmodule ' sandbox ' -  gt;~ /。Cargo/git/checkouts/substrate - 7 e08433d4c370a21/83 a6f1a/primities/sandbox/SRC /../ without_std。SandBox::memory_teardown (self。Memory_idx);| ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^不在“SandBox”中找到错误[E0425]: cannotfindfunction ' memory_new ' inmodule 'SandBox' -  gt;~ /。Cargo/git/checkouts/substrate - 7 e08433d4c370a21/83 a6f1a/primities/sandbox/SRC /../ without_std。Rs: 72:18 | 72 | matchsandbox:: memory_new (initial and maximum){|…

现在是时候检查一下是否可以正确地编译所有内容了:

cargocheck

添加合同托盘

现在我们已经成功导入了契约托盘板条箱,我们需要将它添加到运行时中。不同的托盘(模块)需要使用不同的对应物。对于合同托盘,我们将使用进度表类。在运行开始时,添加这一行和其他pub使用语句。

运行时/ SRC / lib。Rs

AddThisLine / * * * * * * / / / ImportingthecontractsScheduletype pubusecontract:: scheduleascontrtsschedule;契约特质的实施

每个托盘都有一个配置特性,称为必须在操作期间实现的特征。

要确切地找出我们需要为这个托盘实现什么,请查看框架’contract::Trait’文档[10]。对于我们的运行时,实现将看起来像这样:

运行时/ SRC / lib。Rs

/ / ThesetimeunitsareDeFinedinnumberofblocks。/ *——"- * * * * * *添加this block / / / /公共组件:Balance = 1 _000_000_000;警察:余额= 1000 *千分之几;公共资金:余额= 100 *美分;/ * * * * * * EndAddedBlock impltimestamp:: TraitforRuntime - "- * /} {/ * / * * * * * AddThisBlock/parameter_types!{pubconsttombstone存款:余额= 1 *美元;PubconstRentByteFee:余额= 1 *美元;PubconstRentDepositOffset:余额= 1000 *美元;公共收费:余额= 150 *美元;} implcontract:: TraitforRuntime {typeTime = TimestAMPLTypeRandomness = RandomnessCollectieFlip;TypeCall =电话;TypeEent =事件;合同::simpleaddress行列式lt;Runtimegt;;合同::TrieIdFromParentCounterlt;Runtimegt;;TypeRentPayment = ();typesignedclaim差点=合同::DeFiaultsignedclaim差点;TypeTombstoneDeposit = TombstoneDeposit;TypeStorageSizeOffset =合同::DefaultStorageSizeOffset;TypeRentByteFee = RentByteFee;TypeRentDepositOffset = RentDepositOffset;TypeSurchargeReward = SurchargeReward;TypeMaxDepth =契约::DefaultMaxDepth;TypeMaxValueSize =合同::DefaultMaxValueSize;EndAddedBlock} / * * * * * * * /

我们将以类决定econtractaddress类为例,更详细地研究它。 您可以从“确定econtractaddress”文档[11]中看到,它需要trait ContractAddressFor。合同::simpleaddress行列式实现中的托盘本身具有这种类的特征,因此我们可以使用实现来满足我们的合同::Trait。在这一点上,我真的建议你浏览合同栈板[12]的源代码,无论在过程中有问题或你想了解更多。将契约添加到construct_runtime!宏

接下来,我们需要向construct_runtime添加一个托盘!宏。为此,我们需要确定托盘的公开类,以便我们可以告诉托盘的存在。完整的可能类列表可以在“construct_runtime!”“宏观文献[13]。

如果我们仔细看合同托盘,我们知道它有:模块存储:因为它使用decl_storage!宏。模块事件:因为它使用decl_eent!宏。可调用函数:因为它在decl_module中有可分派的函数!宏。配置值:因为decl_storage!宏有config()参数。来自decl_module的模块类!宏。

因此,当我们添加一个托盘,它将看起来像以下:

运行时/ SRC / lib。Rs

Construct_runtime !(pubenumRuntimewhereBlock = Block, NodeBlock =不透明::Block, uncheckedextr= uncheckedextr{/ * - "- * * * * * * AddThisLine/ contract: contract:: {Module, Call, Config, Storage, Eentlt;Tgt;}});

注意,不是所有的托盘揭示所有这些托盘类,有些可能揭示更多!您应该始终查看托盘源代码或托盘文档,以确定您想要公开的类。

这是检查运行时到目前为止是否正确编译的另一个好时机。虽然运行时应该被编译,但是整个节点还没有被编译。因此,我们只使用这个命令来检查运行时。

Cargocheck -节点-模板-运行时公共契约API

某些面板(包括契约面板)公开定制的运行时api和RPC端点。对于契约面板,这允许从链外部读取契约状态。

它可以在我们的链中使用,而不需要在契约托盘上启用RPC调用。但是,我们将执行此操作来调用节点的存储,而不进行事务处理。

让我们首先在container.toml中添加所需的API依赖项。

运行时/货物。Toml

(依赖关系。合同- RPC运行时- API] git = 'https://github.com/paritytech/substrate.git'默认-功能= falsepackage = '托盘-合同- RPC运行时- API'版本= '0.8.0 - alpha。8' tag = '8 2.0.0 - alpha '

运行时/货物。Toml

[功能]DeFiault = [" STD "] STD =[#——snip——'whiss-rpc-runtime-api/STD ',]

要获取契约变量的状态,我们必须调用getter函数,该函数返回带有执行状态的ContractExecResult包装器。

我们需要将返回类添加到运行时。将它添加到其他使用语句中。

运行时/ SRC / lib。Rs

/ * * * * * * AddThisLine usecontracts_rpc_runtime_api:: ContractExecResult;/ * - "- * /

现在,我们已经准备好实现契约运行时API。在运行时结束时,这将在impl_runtime_apis时发生!在宏。

Impl_runtime_apis !{/ * - "- * * * * * * AddThisBlock/ implcontrts_rpc_runtime_api:: contrtsapilt;块,AccountId,平衡,BlockNumbergt;ForRuntime {fncall (origin: AccountId, dest: AccountId, alue: the Balance, gas_limit: u64, input_data: Veclt;U8  gt;)-  gt;bare_call (origin, dest) into (), alue, gas_limit, input_data);Matchexec_result {Ok () =  gt;ContractExecResult:: Success {status: . tatus, data: 。d ata,}, Err (_) =  gt;fnget_storage (address: AccountId, key: [u8;32],) -  gt;{contract:: get_storage (address, key)} fnrent_projection (address: AccountId,) -  gt;Contracts_primities: RentProjectionResultlt;BlockNumbergt;{contract:: rent_projection (address)}} / EndAddedBlock * * * * * * *}

这是检查运行时到目前为止是否正确编译的另一个好时机。

Cargocheck - pnode -模板-运行时

更新外部节点

到目前为止,我们已经完成了向运行时添加托盘的工作。现在让我们将注意力转向外部节点,它通常需要一些相应的更新。对于contract面板,我们将添加自定义RPC端点和启动配置。添加RPC端点

公开适当的运行时API。现在,我们将RPC添加到节点的服务中,以调用该运行时API。因为我们现在在外部节点中工作,所以我们不构建no_std,也不需要维护专用的STD特性。

一旦公开了适当的运行时API。现在,让我们将RPC添加到节点的服务以调用运行时API。因为我们现在处理的是外部节点,所以我们不是在no_std上构建的,也不需要维护专用的STD功能。

节点/货物。Toml

[依赖项]# - "- jsonrpc - core = '14.0.5'[依赖项。托盘-合同- RPC] git = 'https://github.com/paritytech/substrate.git'版本= '0.8.0 - alpha。8' tag = '2.0.0 - alpha。8[依赖性。Sc xml-rpc] git =' https://github.com/paritytech/substrate.git 'tag =' 8 '2.0.0 - alpha。

节点/ SRC /服务。rs

Macro_rules !New_full_start {($config: expr) =  gt;{{* * * * * * * AddThisLine usejsonrpc_core:: IoHandler;

Substrate提供了一个与节点交互的RPC。但是,默认情况下,它不包含对契约托盘的访问。要与托盘进行交互,我们必须扩展现有RPC并添加契约托盘及其API。

/*——snip——*/ Ok(import_queue)})?/ /  lt;-删除分号/***添加这个区块***/。With_rpc_extensions (| builder |→Resultlt;IoHandlerlt;Sc_rpc: Metadatagt;, _  gt;{let handler = pallet_contrts_rpc::Contracts::new(builder)客户端().clone ());让委托= pallet_contrts_rpc:: contrtsapi:: to_delegate (handler);设mut IO = IoHandler::DeFiault();IO。Extend_with(委托);好(IO)}) ?;/*** End添加块***/ (builder, import_setup, inherent_data_proiders)}}初始配置

并不是所有的托盘都有初始配置,但是如果您有一个,您可以从它的文档中学习。例如,’pallet_contracts::GenesisConfig’文档[14]描述了您需要在一个托盘上描述的所有字段。

初始配置由节点/ SRC /chain_spec.rs控制。我们需要修改这个文件,在顶部包含类contrtsconfig和合同价格单元。

节点/ SRC / chain_spec。Rs

Usenode_template_runtime:: {contrtsconfig contrtsschedule};

然后在testnet_genesis函数内部,我们需要将契约配置添加到返回的GenesisConfig对象中,如下所示:

注意:我们从函数参数中获取值_enable_println。请确保删除参数定义之前的下划线。

Fntestnet_genesis (initial_authorities: Veclt;(AuraId GrandpaId)  gt;, root_key: AccountId, ed_accounts: Veclt;AccountIdgt;, _enable_println: bool) -  gt;合同:Some (contrtsconfig {current_schedule: contrtsschedule {enable_println,..)默认值::默认()}}),/ * * * * * * EndAddedBlock /}}

运行升级链

现在可以编译并运行具有契约功能的节点了。以发布模式编译节点

Cargobuild——释放

在运行该链之前,我们首先需要清除该链,以删除旧的运行时逻辑并初始化契约托盘的配置。您可以升级链而不清除它,但这超出了本教程的范围。

。/ target/release/node - templatepurge - chain - de. / target/release/node -模板- de

添加其他框架托盘

在本指南中,我们具体描述了如何导入一个托盘,但每个托盘(模块)将是不同的,如本指南开头所述。不用担心,您总是可以参考示范底层节点运行时[15],它几乎包括框架中的每个托盘(模块)。

在车棚。当底层节点运行时,您将找到如何导入每个不同托盘的示例。在lib. Rs文件中,您将了解如何将每个托盘添加到您的运行时。你基本上可以把你在里面做的事情复制到你的运行时中。在极简主义教程[16]中了解关于在您自己的包中编写运行时的更多信息。现在你的节点已经准备好运行智能合同,转移到承印物油墨!在智能契约[17]下提供了关于准备运行时api[19]和自定义rpc[20]的详细教程。衬底配方[18],如本教程中讨论的那些。了解链规范[21]文件,以定制您的Genesis配置。帧“合同”托盘API[22]参考链接[1]

底层节点模板:https://github.com/substrate-deelope-hub/substrate-nodetemplate [2]

框架:https://www.substrate.io/kb/runtime/frame [3]

合同托盘:https://docs.rs/crate/pallet-contracts/2.0.0-alpha。8 [4]

创建你的第一个底物链:https://www.substrate.io/tutorials/creyour-firstsubstrate-chain/2.0.0-alpha.8[5]

底层节点模板:https://github.com/substrate-deelope-hub/substrate-nodetemplate [6]

正式文档:https://doc.rust-lang.org/cargo/reference/index.html [7]

平衡托盘:https://docs.rs/crate/pallet-balances/2.0.0-alpha。8 [8]

性病:https://doc.rust-lang.org/std/ [9]

No_std: https://rust-embedded.github.io/book/intro/no-std.html [10]

合同::Trait文档:https://docs.rs/pallet-contrts/2.0.0-alpha.8/pallet_contrts/trait.trait.html [11]

DetermineContractAddress文档:https://docs.rs/pallet-contracts/2.0.0-alpha.8/pallet_contracts/trait.Trait.html associatedtype。DetermineContractAddress [12]

合同托盘:https://github.com/paritytech/substrate/blob/2.0.0-alpha.8/frame/contrts/src/lib.rs [13]

Construct_runtime !宏文档:https://docs.rs/frame-support/2.0.0.0 – alpha.8/frame_support/macro.construct_runtiing.html [14]

Pallet_contracts:: GenesisConfig document: https://docs.rs/pallet-ts/2.0.0-alpha.8/pallet_contrts/struct.genesisconfig.html [15]

运行时模底层节点:https://github.com/paritytech/substrate/blob/2.0.0-alpha.8/bin/node/runtime/[16]

在包运行时中编写极其简短的教程:https://www.substrate.io/tutorials/pallet-inowcrate/2.0.0-alpha.8[17]

衬底墨水!智能合同:https://www.substrate.io/kb/smart-contracts [18]

用于配方的底物:https://substrate.de/recipes/[19]

运行时api: https://substrate.de/recipes/3-entrees/runti-api.html [20]

定制rpc: https://substrate.de/recipes/3-entrees/customrpc.html [21]

链规格:https://www.substrate.io/kb/integrate/chain-spec [22]

框架契约托盘API: https://docs.rs/pallet-contrts/2.0.0-alpha.8/pallet_contrts/index.html

欢迎学习承印物:

https://substrate.de/

对基质发展的关注:

https://github.com/paritytech/substrate

遵循圆点花纹的进展:

https://github.com/paritytech/polkadot

申请训练营:

https://bootcamp.web3.foundation/

温馨提示:

文章标题:在运行时的衬底中添加契约模块

文章链接:https://www.btchangqing.cn/22851.html

更新时间:2020年05月19日

本站大部分内容均收集于网络,若内容若侵犯到您的权益,请联系我们,我们将第一时间处理。

在运行时的衬底中添加契约模块1
区块链

比特币贬值一半后,2.2亿美元从交易所“逃离”

2020-5-19 19:31:40

区块链

赵长鹏可能在推特上犯了埃隆·马斯克式的错误

2020-5-19 21:04:00

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索