给开发者的 CosmWasm 介绍


原文链接:

原文作者:Ethan Frey

CosmWasm 是为Cosmos 生态系统建造的一个新型智能合约平台。如果你从未听说过它,请先阅读这篇入门级文章:CosmWasm宣布正式启动。本文的目的是给那些想把CosmWasm 融入到他们产品中的开发者更深入的介绍一下这项技术。尤其是针对那些有Cosmos SDK开发经验的Go语言开发者和在寻求区块链平台的Rust语言开发者。

Cosmos SDK:

https://github.com/cosmos/cosmos-sdkhttps://mp.weixin.qq.com/s/iVXDO010WD4zP_olunuXFQ

在2019年柏林区块链周上,Gaians团队开发出CosmWasm的原型。Aaron Craelius提出了该体系结构,尤其是避免可重入,Jehan Tremback引导使用Rust语言编程,Ethan Frey实现了Go语言的实施。成功的原型制作完成后,Interchain基金会给Confio提供了资助,为了能创造出可在对抗环境中使用的强大版本。本文向开发人员介绍了该资助的工作成果,并提出了未来可能的方向。

CosmWasm的原型:

Confio:

http://confio.tech/

如何使用CosmWasm?

CosmWasm作为Cosmos SDK中的一个模块。这就意味着基于Cosmos SDK构建的区块链可以快速并且在不用去调整现存逻辑的情况下加入CosmWasm智能合约来支持他们的区块链。并且提供了集成到gaiad二进制文件中的名为wasmd的CosmWasm示例二进制文件,因此您可以使用已记录和经过测试的工具以及与Cosmos Hub相同的安全模型,立即启动一个最新的支持智能合约的区块链。

wasmed:

需要一个运行中的区块链来托管该合约并通过应用程序使用它们。本教程将说明如何设置一个本地的“ dev net”。并计划发布一个托管测试网,所有开发人员都可以将其合约上传到该测试网,以便轻松运行演示并与其他人共享他们的合约。

一旦拥有支持CosmWasm的区块链,就可以部署自定义合约。这在原理上与以太坊相似,但是细节上有许多差异。由于大多数人都熟悉这种流程,因此让我们看一下有哪些主要的异同点:

CosmWasm教程:

与Solidity智能合约对比

当大家提及“智能合约”时,首先会想到以太坊和Solidity。由于大多读者都熟悉使用这个系统,这里我会强调一下他们的共同点与差异。

首先,部署-执行过程由3个步骤组成而不是2个步骤。以太坊是围绕许多特殊智能合约的概念构建的,每个合约都可能是为任意双边协议定制的,但事实证明编写无缺陷程序合约比原先想象的要难,并且大多数是标准模板(如OpenZepellin)的副本。考虑到这一点,而且意识到上传和验证wasm代码的开销,我们定义了合约的以下三个阶段:

  1. 提交代码-提交一些优化的wasm代码,没有状态或合约地址(例如标准ERC20合约)
  2. 实例化合约—实例化具有某种初始状态的代码引用,创建新地址(例如为ERC20通证设置通证名称,最大发行量等)
  3. 执行合约—这可能支持许多不同的调用,但是它们都是先前实例化合约的无特权使用,取决于合约设计(例如:发送ERC20通证,批准其他合约)

就像以太坊一样,合约的实例化和执行是按需计量的,需要耗费大量gas。此外,实例化和执行都允许签名者将一些通证与消息一起发送到合约中。其中,两个主要区别是直接将通证发送到合约中。例如通过SendMsg(如果可能)不会触发任何合约代码。这是减少潜在攻击媒介的明确设计决策。它使一切变为可能,但是需要明确要求所有合约的执行。

合约安全性

在区块链智能合约中,代码正确性至关重要。由于源代码是公开的,并且没有“管理员”来解决问题,因此在执行路径中一定不能存在可被利用来产生不良(或未定义)行为的缺陷。许多团队希望使用图灵不完备的语言来进行更深入的分析并消除许多故障类别。我们选择使用图灵完备语言(例如Solidity),但以安全性为主要目标。这不仅包括限制可能的攻击面,还包括非常强大的内置单元测试功能,可以在部署之前轻松消除漏洞。

尽管CosmWasm发展的学习曲线比Solidity更复杂(要想正常运行您的第一个示例合约肯定需要付出更多精力),但它的设计目的是使具有两周经验的开发人员以更高效的生产力创造出可用于生产就绪的代码。我们希望拥有一种体系结构和工具来避免整个行业都需要“ CosmWasm智能合约审核员”,因为“做正确的事”应该很容易。

可重入性是以太坊中的一类主要攻击(由于DAO攻击,他可能是最臭名昭著的)。CosmWasm的设计旨在消除此类攻击的可能性:

https://www.cosmwasm.com/docs/intro/smart-contracts#avoiding-reentrancy-attacks

就像以太坊一样,我们非常重视资源使用。因此,我们对内存使用情况进行了严格限制,并对CPU和存储提供了基于gas的限制:

https://www.cosmwasm.com/docs/intro/smart-contracts#resource-limits

对于非常重视安全性的人,这里有一个更长的清单,了解CosmWasm如何抵挡已知的以太坊攻击媒介:

https://www.cosmwasm.com/docs/intro/smart-contracts#lessons-learned-from-ethereum

CosmWasm入门

如果您急于入门,可以直接查看我们的第一个教程:

这会引导您完成修改现有合约,进行编译,将其部署到本地“ dev net”以及完成通过命令行工具运行合约的过程。

使用Rust编程语言编写合约

一旦你会使用rust语言编程,编写合约将非常简单。万一不会的话,在已经存在的合约上进行细微的改动也是非常简单明了的,就只是修改一下语法。在本次教程中,我们会带你了解rust基础知识并且介绍如何编写合约,但如果你是一个高级rust开发者,并且想深入研究代码(并审查质量),请参考以下一些指针,以了解CosmWasm 代码库。

CosmWasm是一个提供构建合约所需的所有模块的代码库。而且cosmwasm-template

包含一个入门包,可以快速建立最小合约以及构建系统和单元测试,因此您可以直接开始编写自定义逻辑。这两个库都提供了关于如何构建它们的一个更深入的文档。如果要编写自己的合约,请按照cosmwasm-template上的说明进行操作,然后开始编辑contract.rs。

cosmwasm:

cosmwasm-template:

要了解如何构建合约,请查看一个简单的托管代码。状态是数据库中保留的内容。发送一次InitMsg,根据通用代码创建合约。其中包含有关托管方的信息以及超时。HandleMsg是一个枚举类型变量(enum),包含可以发送的所有可行的消息。除了直接调用函数外,我们可以为每个调用枚举匹配来执行适当的逻辑。这样做的好处是可以轻松地序列化调用,以及明确定义哪些函数是公共的。最后,QueryMsg提供了一个枚举,以允许多种方式查询合约的状态(每种可能在只读存储区上执行的代码)。

托管代码:

InitMsg:

入口点在lib.rs中定义。它们处理了rust类别和wasm外部FFI接口之间的一些标准转换,但是在那里不保留任何实际逻辑,只允许您使用Vec 和Result <Response,Error>而不是裸指针,并通过 FFI边界手动序列化错误信息。真正的逻辑在您的contract.rs文件中。init是从此代码构建新合约的入口点,并且应定义所有配置选项。处理加载状态并匹配所有受支持的enum值以对合约执行操作。之后,如果托管已过期,我们可以使用try_approve将资金释放给受益人,或者使用try_refund将资金退还给原始发件人。

请注意,为了简化开发和测试,可以单纯用rust语言完成单元测试,并与整个测试工具链和完整回溯一起运行。cargo单元测试将在托管示例中做到这一点。还可以将cargo wasm 一起编译为wasm,并对生成的wasm字节码运行全套的集成测试。集成测试具有与单元测试类似的语法,并且易于开发,但是缺少堆栈跟踪和合约代码上的其他工具。

全套的集成测试:

与链进行更深层次的整合(Go 语言)

之前已经介绍了如何在Rust语言中开发自定义合约,那么让我们转向经验丰富的Cosmos SDK开发人员在Go编程语言方面的潜在可扩展性。所提供的cosmwasm模块是SDK和智能合约VM之间连接的最小,没有倾向的实施。它嵌入在wasmd中,后者是gaiad的分支,并添加了x / wasmd。它会处理所具体实施细节,但是会为您打开该存储库并在其周围添加自定义业务逻辑的领域。以下是一些有关如何自定义的想法:

添加许可或费用-您是否正在建立一个任何人都可以上传合约的平台?还是您打算在不组织完整的链升级过程中使用此功能让链上治理添加新功能?考虑在上传代码或实例化合约时修改处理程序以扣除费用。或者,也许只是将上传的代码作为治理处理程序(提案类型)。当前的实施允许任何人免费上传代码和实例化合约-非常适合测试网,不适用于主网。

增加存储限制-SDK中的当前对于gas限制局限了在一个交易(或一个区块)中可以执行多少次读取和写入操作。但是,它们并没有限制总存储量。例如,合约可以将20个500字节区块写入磁盘。下次还有另外的20个,依此类推。由于您将KVStore递给合约,因此可以包装一层来提供一些限制。就像每个合约执行时的一次写入(或一次写入新密钥)一样。或者,在所有执行中,合约KVStore中存储的密钥的总数限制。又或者创建者需要预付存储空间(购买或租用),这便定义了限制。所有这些业务逻辑都可以用Go语言直接编写,而无需对基础合约进行任何更改(除非防止某些违反这些限制的合约)。

支持OpaqueMsg-当前的CosmWasm规格允许输出OpaqueMsg变体。这是一种消息类型,它不会被智能合约代码解析或创建,只是从客户端传递到合约再传递到SDK。您可以将其用于多重签名,客户提出一些要求(可能是质押),必须经过批准才能在合约许可下执行。正如合约可以发送SendMsg一样,它也可以发送这样的OpaqueMsg。不需要更改VM或合约,而需要使用SDK模块解析出的清晰格式,然后将其分配给具有多个模块的路由器。然后,一些客户端支持以这种格式创建(未签名)消息,作为合约调用主体的一部分。是sdk.Msg实现的go-amino json表示形式吗?Base64编码的go-amino二进制表示形式?还是一些完全不同的编码?只要您的模块和客户端同意这个格式,它对于CosmWasm VM就是完全不透明的。当前的实现将其保留为TODO,供链开发人员自定义所需的方式。

几乎所有的加密经济和治理设计决策都可以通过分叉Go模块来实现。如果您有任何看法,请提出一个问题,或者分叉代码并实现它。我们很乐意审查您的PR。

在此处提问:

审查PR:

未来的工作

CosmWasm,VM和平台都已处于可用的alpha版本状态,我们正在努力完善最后的问题,以使其能够投入生产。在此项目中,目前正在跟踪一些较小的修复程序使其可以做好主网准备。除此之外,我们还希望围绕它构建工具,并迭代新功能,最理想的是关注实际用户的需求。当前路线图上的一些要点是:

启动并维护一个公共测试网,以便任何人都可以试验合约。

添加对现有Cosmos工具的支持,例如该网络上的区块浏览器和钱包。

收集标准化合约以激发开发灵感(例如OpenZeppelin),并提供文档和教程来帮助新手开发人员。

创建一个网站,以验证wasm字节代码后面的rust代码,例如etherscan。构建系统已经构建,但是需要Web前端:

设置注册表以共享合约(或提供一种使用crates.io的好方法)。

提供简单的JS API,以实例化和执行合约以启用dApp开发,并提供一个演示dApp。

提供与IBC的集成(当golang的实施稳定时),以允许通过智能合约进行多链交互。

我们也非常渴望获得社区的反馈来影响某些设计,例如查询:

预编译,甚至是用于合约开发的第二种语言:

以及将促进与标准Cosmos SDK模块进行更深入集成的具体用例和应用程序。

联系我们

请阅读文档:https://www.cosmwasm.com/

并使用我们的入门学习手册:

如果有任何疑问,或者想要有关如何将CosmWasm与应用程序集成或在其之上进行构建的建议,请随时与我们联系。

邮箱:cosmwasm@confio.tech

CosmWasm 电报组:https://t.me/joinchat/AkZriEhk9qcRw5A5U2MapA

官网:http://confio.tech/

博客:https://medium.com/confio

本文表达的是All In Bits Inc(dba Tendermint Inc)的观点,并不一定代表Interchain Foundation的观点或行为。