【以太坊】关于以太坊智能合约在项目实战过程中的设计及经验总结 | 猿创征文

陶然同学 2022-06-18 08:11:15

🔎这里是【以太坊】,关注我学习以太坊不迷路
👍如果对你有帮助,给博主一个免费的点赞以示鼓励
欢迎各位🔎点赞👍评论收藏⭐️

👀专栏介绍

【以太坊】 目前主要更新以太坊,一起学习一起进步。

👀本期介绍

本期主要介绍关于以太坊智能合约在项目实战过程中的设计及经验总结

1.智能合约的概述

近几年,区块链概念的大风吹遍了全球各地,有的人觉得这是一个大风口,有的人觉得他是个泡沫。众所周知,比特币是区块链1.0,而以太坊被称为了区块链2.0,而区块链1.0和2.0最主要的差别就在于以太坊拥有了智能合约。其实,智能合约在1994年就已出现,计算机科学家和密码学家NickSzabo首次提出智能合约概念。早于区块链概念的诞生。Szabo描述了什么是“以数字形式指定的一系列承诺,包括各方履行这些许诺”的协议。虽然有它好处,但智能合约的想法一直未取得进展—主要是缺乏可以让它发挥出作用的区块链。

从技术角度理解,智能合约其实是一个语法简单、指令集精简的图灵完备的语言,就像简化版的JavaScript。智能合约和其他的语言的区别主要在于,一方面,智能合约和代币体系完美结合,能够完成一系列价值转移,另一方面,智能合约会在所有节点统一执行,根据确定的输入、确定的代码保证确定的输出,也是所有节点状态一致性的保证。最后是智能合约都由有外部触发调用,不存在什么定时调用等。

废话不多说,接下来,本人就从技术角度,来说说智能合约方面的设计。

2.智能合约的分层设计

2.1分层设计说明

智能合约的分层设计模型主要是借鉴gitHub上的一篇名为《 浅谈以太访智能合约的设计模式与升级方法》文章的中心思想,其作者也是基于其多年的Java实战经验提出的一些智能合约设计思路。该文章有许多借鉴之处,但也存在许多坑点没有仔细考虑。文章的分层设计思路主要如下:

“业务逻辑与外部解耦、业务逻辑与数据解耦”是Java设计模式的一种策略,也是其文章的主要思想。其实现方式主要将合约拆分为代理合约、业务控制合约、业务数据合约、命名控制器合约。其中代理合约是用于业务逻辑与外部Dapp的解耦,业务控制合约、业务数据合约和命名控制器合约是用于业务逻辑与数据的解耦。作者在设计时,也拆分了几种不同的场景,详见如下:

控制器合约与数据合约1—>1:

控制器合约与数据合约1—>N:

控制器合约与数据合约N—>1:

控制器合约与数据合约N—>N:

此类情况可以拆解为上面三种情况的组合。

2.分层设计实现关键点

1)合约与合约之间的调用

合约调用合约的实现主要有两种方式,第一种方式是可以通过 call、delegatecall、 callcode方法实现对其他合约的方法的调用,但是其弊端是使用存在安全性问题,而且不能获知被调用合约的执行结果,不建议使用。第二种方式,是通过在合约中“外部引用”被调用的外部合约进行实现。

通过合约“外部引用”实现调用外部合约需要注意以下几点:

  • 合约对象中需要定义被应用合约对象的方法,否则合约中无法识别被应用对象,编译器会报错;
  • 被引用对象需要通过合约对象的设置外部合约方法将合约对象进行引入,注意需要引入外部合约对象后。

2)合约与合约之间的转账

合约可以接收转账,需要显示声明回调函数,并在回调函数上加payable进行修饰。合约与合约之间进行转账时,需要在合约中显示用send或者transfer进行合约之间的转账,合约与合约之间的转账将以内部交易的形式执行。另外,在显示转账的方法中也需要加payable修饰。

pragma solidity ^0.4.2;

contract  Test{

function TTest(address contractAddress,uint amount)  payable {

   contractAddress.transfer(amount);

    }

    function()  payable {

    }

}

2.3分层设计的局限与问题

1)被调用合约的方法的数据返回限制

被调用合约在返回string/bytes等不定长类型时会存在问题。这种限制需要在设计被调用合约时要注意,在实际项目中业务逻辑合约和数据合约都属于被调用合约,故而其设计公共方法时需要规避string/bytes等不定长的限制问题。以下是一个调用失败的反例:

pragma solidity ^0.4.2;

contract  Test{

function TTest(address contractAddress,uint amount) {

   A a=A(contractAddress);

  //编译会报错

   string temp=a.getString();

    }

}

2)被调用合约的方法的返回参数长度限制

被调用合约在返回定长的数据时,不能返回超过32位长度的数据,例如bytes33/uint33编译器将会提示错误。

3)被调用合约结构体数据返回限制

Solidity语言中,在编译器0.4.17版本之后,可以支持struct结构体的数据返回。在返回结构体的情况下,编码需要注意添加“pragma experimental ABIEncoderV2;”,需要注意的是结构体中也不能包含string/bytes等不定长数据类型,但是返回struct这种形式还处于试验阶段,稳定性安全性有待论证。(在0.4.17版本之前不能使用因为以前编译器没有把struct作为一个真正的类,只是形式上的组合在一起)

pragma solidity ^0.4.17;

pragma experimental ABIEncoderV2;

contract  Test{

    struct MyStruct { int key; uint deleted; }

function TTest() returns() {

   return MyStruct({key:int(1),deleted:uint(1)});

    }

}
...全文
119 回复 打赏 收藏 举报
写回复
回复
切换为时间正序
请发表友善的回复…
发表回复
发帖
Ethereum中文社区
加入

171

社区成员

这里是由区块链、以太坊、Web3.0、元宇宙等相关技术组成的国内最大的开发者聚集地,帮助社区成员快速获得更全面、更深度的技术信息,链接更多资源,让开发者更好地入门学习、成长与应用实践。
社区管理员
  • ETHPlanet
  • 活动助手
帖子事件
创建了帖子
2022-06-18 08:11
社区公告

Hi,欢迎加入我们!

 

在这里你可以:

  • 获取最官方最新最全的区块链、以太坊、Web3.0学习内容与资源
  • 获取行业内更有价值的研讨会、公开课资源,或参与社区发起的主题活动课程
  • 获得专业的以太坊、区块链、Web3.0相关技术资深专家/讲师的回复或指导,突破学习瓶颈
  • 进行学习打卡、提问或回答问题,提高个人或在社区的影响力,将有机会与各大技术官方深度合作
  • 参与丰富的社区活动,获得更多学习资源、行业资源等
  • 结识更多行业伙伴,参与线上/线下课程、交流会,拓展行业交流圈

 

【最新活动】:

1、6月1日21:00-21:30,DappLearning Infura AMA(线上)点击查看详情