×

智能合约的开发和安全指南

标签: 暂无标签
迅雷链开放平台运行流程和接入

1.jpg

为了方便开发者调试,迅雷链提供沙盒环境,开发者在完成本地测试后,先在沙盒环境测试,在沙盒环境开发者可以申请给测试账号充值,调用接口部署合约,并执行合约进行逻辑测试。测试完成后使⽤沙盒环境中的合约地址到迅雷链开放平台提交发布申请。开发者在开放平台提交的合约代码必须和测试环境⼀致。

迅雷链官方审核开发者应用合规后,反馈开发者审核通过,开发者手动执行发布到链上,将区块链应用逻辑里使用的合约地址替换为合约在线上区块链发布后的地址。

关于合约的开发有哪些注意事项

迅雷链底层兼容 EVM,所以推荐开发者使⽤Solidity 语⾔开发智能合约。智能合约,实际上就是存储了代码的区块链账户,其他账户都可以通过给这个账户发送交易实现合约调⽤,以改变合约内存储的状态变量。下⾯是⼀个简单的商品买卖合约代码。

2.jpg

3.jpg

4.jpg

上面的合约,实现了一个简单的商品买卖合约,卖家部署合约并放入双倍商品价格的保证金,买家通过向合约发送交易调用 confirmPurchase 方法,并转入双倍商品价格的链克,来锁定交易,买卖双方在交易确认后,买家再次通过向合约发送交易调用 confirmReceived 方法,确认交易状态,合约向买家转入一倍商品价格的链克,向卖家转入剩余的全部链克,交易结束。

5.jpg

合约中限定了状态、调用者等 modifier,保证交易流程的正确。合约的状态变量记录了买卖双方的账户、商品的价格、交易的状态等信息,通过向合约发送交易调用合约内方法,来改变合约内部的状态变量值,最后这些交易在区块链同步出去,实现了合约代表的交易需求的去中心化。

合约通过 Solidity 语言编写,是当前的合约编写最流行的语言之一。这门语言受 C++,Python 和 Javascript 语言的影响,设计的目的是能在以太坊虚拟机(EVM)上运行。Solidity 是静态类型语言,支持继承、库和复杂的用户定义类型等特性。详细 API 可参考
http://solidity.readthedocs.io/en/develop/index.html

通过 truffle 的智能合约的开发流程

truffle 是一套 Solidity 开发框架,集成了本地区块链环境,可快速编译、部署、调试合约代码。详情可参考
http://truffleframework.com/docs/

1.首先安装 truffle,依赖 nodejs,使用 npm -g truffle 命令安装。新建合约项目文件目录,使用truffle init命令初始化合约工程。

6.jpg

2.新建合约文件 contract/SimpleStorage.sol

3.添加 migrate 代码,新建文件
migrations/2_deploy_contract.js。后面会介绍这段代码的作用。

7.jpg

4.执行 truffle compile 编译合约,编译后的合约在 build 文件夹下。每个合约有一个对应的 json 文件,内含部署所需的
bytecode,abiCode

5.执行 truffle migrate 移植部署合约

8.jpg

6.执行 truffle develop,开启本地区块链环境,对已部署的合约进行测试

合约是通过 EVM(以太坊虚拟机) 来运行的,最终部署在区块链上,同步到区块链的交易中,生成合约账户。

truffle develop 命令可以生成一个本地区块链,并生成 10 个区块链账户,每个账户有 100 的余额。migrate 是 truffle 命令,可以通过执行 migrations 下的脚本,将合约部署到指定的区块链上。truffle.js 可以配置部署和连接的区块链。上面第三步脚本实现的功能就是将 SimpleStorage 合约部署到区块链上,依赖的是 truffle 封装的功能。

truffle develop 生成的控制台环境,是本地区块链环境,内置 web3,并将 migration 里部署的合约实例化到上下文中,可以直接调用。

以太坊 remix 实现合约的部署和调用

除了使用 truffle 框架开发智能合约,还可以通过以太坊提供的 [remix](http://remix.ethereum.org/)
快速实现合约的部署和调用。(由于某些网络原因,可能出现页面部分 js 不能完全加载)

remix 提供了合约的编译运行环境,并可以再控制台看到合约每条交易的详细信息,如输入输出参数,签名后的方法 data,交易 hash 等信息。支持调试。

1.使用 compile detail,可以看到合约编译详情。包括 bytecode,abi 和使用 web3.js 快速部署的方法。

9.jpg

2.使用 run 来 create 合约,控制台可查看创建合约的交易。

10.jpg

remix 功能丰富,提供有本地区块链环境和线上 etherum 连接选择,支持单步调试,并可以看到详细的堆栈内容和 assembly code。简单的合约直接通过 remix 部署和测试十分便捷。但是如果有依赖合约需要导入等方式实现的,不能很好的支持。也可以支持通过 websocket 连接本地项目。

智能合约有哪些安全注意事项?

由于智能合约是通过发送交易部署在区块链上的去中心化应用,这种性质就决定了合约一旦部署和调用操作成功,就不能回退。而合约中所保存状态和转移的资产,都具有重要的价值和意义,所以如果合约代码出现 bug,往往都会产生十分严重的后果。下面介绍一些合约开发过程中需要注意到的部分安全事项。

1.设置函数可视性和合理的 modifier 权限
有对外交互的函数通常设置为 public 或 external,内部函数设置为 private 或 internal。另外,一般使用相应的 modifier 限制函数操作的角色权限。这些都可以有效减少安全问题。

2. send 调用可能失败,需要检测 send 结果然后再确定是否进行下面的状态改变。

11.jpg

通常的操作逻辑可能会使,向某个账户发送一笔交易,然后改变合约内的某些数据状态。但是如果未对 send 函数调用的结果做检测,可能会出现 send 失败,但是后续状态依然被改变的结果,导致状态不一致。

下面例子展示(但并不是一个安全的合约例子):

12.jpg

如果 msg.sender.send 失败,但合约并未抛出异常继续执行,将导致 balances[msg.sender] 为 0,但 msg.sender 并没有转入对应的 balance。所以需要对 send 的结果检测,并使用 throw 异常的方法,回滚已改变的状态值。

3.循环可能导致 gas 被消耗完而引起合约执行失败
循环变量可能依赖外部输入,如果循环的次数过多,将会导致 gas 消耗递增,直至超过 gasLimit,从而使得合约执行失败,回滚状态值,但是对应的 gas 却已经消耗不能退回。

4.调用堆栈深度限制
EVM 调用堆栈限制最深 1024 层,从资源交易占用角度看这是必须的。同时也意味着,如果嵌套调用的数量达到 1024,合约执行将会失败。攻击者可以递归调用一个合约 1023 次,然后再调用合约函数,造成失败一些 send 之类的失败,如上述第一条。

5.溢出漏洞
溢出,就是一个数字增加到它的最大值以上。Solidity 可以处理多达 256 位的数字(高达 2²⁵⁶-1),所以递增 1 会得 0。最佳实践是通过 zeppelin-solidity 提供的 safeMath 来处理数值计算。

13.jpg

上面是 openzeppelin 实现的 safeMath 的乘法运算。如果乘法运算溢出,则 c/a 的结果不会等于 b。以此保证运算的正确性。

6.可重入攻击 (DAO)

在使用 call 来发送 value 时,检测外部条件顺序的不合理或调用者设置 call 或 send 对应 fallback 恶意转账,都可能导致状态不一致和金额的损失。

14.jpg

避免 DAO 攻击最佳实践就是使用 transfer 来实现转账,并使用 require 检测结果。

在合约 A 执行 to.call.value 时,如果 to 地址是合约地址,将会触发 to 的 fallback 函数来接收 value。如果在 to 合约的 fallback 里递归调用了 A 合约的 withdraw 时,就是 DAO 攻击。

7. selfdestruct 的执行参数如果是合约地址,将不会执行合约的 fallback
如果一个合约 A 的 selfdestrcut(sender) 的 sender 是一个合约地址 B,B 合约将不会使用 fallback 来接收 A 的 selfdestruct 带来的转账。由此可能产生绕过合约逻辑的风险。

8.短地址攻击
短地址攻击是针对基于 ERC20 类型的 token transfer 时的问题。在调用 transfer(address addr, uint amount) 时,实际发送交易的是 abi 编码后的 16 进制代码,其中每个参数长度是固定的,如果长度不足会自动补 0。漏洞即源于此,如果 addr 的最后是以 0 结尾的,而攻击者少输入最后的 0,amount 编码高位补 0,导致 amount 编译值比实际输入值大。从而实现转移超出实际应该 transfer 的数量的 token。实践中,需要在 transfer 方法检查长度来限制此类问题。

合约的安全实践需要持续的关注和更新,并做好合约的审计和升级,必要情况下可设置一些紧急停止或转移合约功能的方法,以备不时之需。


思桦

写了 23 篇文章,拥有财富 276,被 11 人关注

反对反对
回复

使用道具

B Color Link Quote Code Smilies

成为第一个吐槽的人

Archiver|手机版|小黑屋|迅雷链开发者社区
Copyright©2018 onethingcloud.com All Rights Reserved 深圳市网心科技有限公司版权所有 粤ICP备14008884号-23
返回顶部