Solidity 类特性
本文讨论 Solidity 的类特性
> * 原文链接:https://medium.com/coinmonks/class-features-provided-by-solidity-84ee97840666 作者:[Jules Goddard](https://medium.com/@plaxion) > * 译文出自:[登链翻译计划](https://github.com/lbc-team/Pioneer) > * 译者:[翻译小组](https://learnblockchain.cn/people/412) > * 校对:[Tiny 熊](https://learnblockchain.cn/people/15) > * 本文永久链接:[learnblockchain.cn/article…](https://learnblockchain.cn/article/3032) 本文讨论 Solidity 的类特性,Solidity 是以太坊区块链的默认智能合约语言。 ## 背景 在 Datona 实验室的 Solidity Smart-Data-Access-Contract(S-DAC)模板的开发和测试过程中,我们探索了使用类的技术,就像在传统的面向对象的编程(OOP)语言中一样。例如,我们希望能写出类似这样的代码: ``` import "ContractOwner.sol"; import "Partners.sol"; contract EasyShare ... { ContractOwner contractOwner; Partners partners; ... function addPartner(...) public onlyContractOwner { partners.add(...); } ... } ``` 在这个例子中,`ContractOwner` 和 `Partners` 是我们想要使用的类。 一个类将相关的代码和数据封装在一个实体中。 关于这个的实现将在下面的例子中进一步探讨。 ***为什么在 Solidity 中使用类?*** 因为我们很习惯在 OOP 开发中使用类,并且想要继续以这种方式来开发,因为它很好用。 对于为什么要用 OOP 编程,其可能的原因有很多。参考wiki中的[面向对象编程](https://en.wikipedia.org/wiki/Object-oriented_programming)。 ***在 Solidity 中使用类有什么好处?*** 我们发现,OOP 是非常熟悉、自然的,通常可以减少错误率,便于独立测试,并能重用。 ***在 Solidity 中使用类的缺点是什么?*** 主要的缺点是可能会使我们不去完全使用 Solidity 的编程范式。 还有人担心,大量导入文件会成为维护的噩梦。 最后,Solidity 合约通常非常简单,而导入文件可能会增加不必要的复杂性、成本和文件管理。 尽管如此,我们认为值得探索各种可能性,即使只是为了拒绝它们。 ## Solidity 类特性 Solidity 已经有很多与现代 OOP 语言非常不同的特性,如:合约、可支付账号(payable account);执行的 Gas 消耗;永久存储;全局执行等等。 然而,*合约不是类*,因为Solidity有函数调度程序和其他开销,调用其他合约的函数是非常昂贵的。我在另一篇文章中有提到过“[Solidity 函数的 Gas 消耗](https://learnblockchain.cn/article/2716) ”。 Solidity 提供了哪些功能来实现将代码和数据封装在类里呢? 下面我们将开始探讨: ``` 1) 导入文件 2) 合约继承 3) 将库附加到结构体 ``` 在所有这些功能中,数据和函数都可以使用类似类的点符号。例如:`myClass.myFunction(myArgument)`。在某些情况下,也可以不用指定类。 ### 1)导入文件 有一下几种情况,我们应该作为一个单独的实体文件保存,然后再导入它们,例如: #### 1.1) 其他合约 在 Solidity 中,合约有可能创建其他合约。除了为测试而创建的临时合约外,那些其他合约似乎很有可能是在不同的文件中被定义: ``` import "OtherContract.sol"; contract MyContract ... { OtherContract otherContract; constructor(...) public ... { otherContract = new OtherContract(...); } ... } ``` #### 1.2) 继承的合约 在 Solidity 中,也可以继承合约。并且,除了为测试而创建的临时合约外,继承的合约似乎很有可能被重复使用,所以在一个单独的文件中定义很重要,在下面(2)会进一步探讨。 #### 1.3)库 在 Solidity 中也可以创建库,库函数可以是外部或内部的。任何包含外部函数的库大概都是为了被其他合约重用,所以应该在一个独立的文件中定义。 ``` import "SortLibray.sol"; contract MyContract ... { MyStruct data; ... function sortData(...) internal ... { SortLibrary.sort(data); } ... } ``` 包含内部函数的库将与合约的字节码一起被打包。这些将在(3)中讨论。 ### 2) 合约继承 在 Solidity 中,有两种方式可以有效地提供类特性,一种是*继承基础合约*。 被继承的基础合约是一个普通合约,包含数据和可以作用于这些数据的函数,但通常是不完整的,或者说只是完整合约的一个片段。恰当的文件命名习惯是很有用,可以清楚知道哪些合约是作为可继承的基础合约。 我们还可以把继承当做对象组合来使用,这在下面的例子中会讲到。 ### 3) 将库附加到结构体 这是另一种有效提供类特性的方式,这种方式是创建一个结构体并附加一个库,库中的函数接受该结构体。这就是*将一个库附加到一个类型*(通常是一个结构体)。 在希望使用该类的合约中,声明了结构体的变量,并可提供结构体作为参数来调用库函数。 Solidity 提供了一个编译器指令,以支持使用点符号调用库函数,这就是`using for`( *using library for struct*)。这个功能也可以用于扩展标准类型,例如, `using NumbersLib for uint`。 看看下面的例子。 ## 一些使用 Solidity 类特性的例子 我们用一个简单的合约来演示类特性技术。 这个版本的合约,使用一个叫做`ContractOwner`的基础合约和一个叫做`Partners`的组件类。 ```js import "ContractOwner.sol"; import "Partners.sol"; co...
- 原文链接:https://medium.com/coinmonks/class-features-provided-by-solidity-84ee97840666 作者:Jules Goddard
- 译文出自:登链翻译计划
- 译者:翻译小组
- 校对:Tiny 熊
- 本文永久链接:learnblockchain.cn/article…
本文讨论 Solidity 的类特性,Solidity 是以太坊区块链的默认智能合约语言。
背景
在 Datona 实验室的 Solidity Smart-Data-Access-Contract(S-DAC)模板的开发和测试过程中,我们探索了使用类的技术,就像在传统的面向对象的编程(OOP)语言中一样。例如,我们希望能写出类似这样的代码:
import "ContractOwner.sol";
import "Partners.sol";
contract EasyShare ... {
ContractOwner contractOwner;
Partners partners;
...
function addPartner(...) public onlyContractOwner {
partners.add(...);
}
...
}
在这个例子中,ContractOwner
和 Partners
是我们想要使用的类。
一个类将相关的代码和数据封装在一个实体中。
关于这个的实现将在下面的例子中进一步探讨。
为什么在 Solidity 中使用类?
因为我们很习惯在 OOP 开发中使用类,并且想要继续以这种方式来开发,因为它很好用。
对于为什么要用 OOP 编程,其可能的原因有很多。参考wiki中的面向对象编程。
在 Solidity 中使用类有什么好处?
我们发现,OOP 是非常熟悉、自然的,通常可以减少错误率,便于独立测试,并能重用。
在 Solidity 中使用类的缺点是什么?
主要的缺点是可能会使我们不去完全使用 Solidity 的编程范式。
还有人担心,大量导入文件会成为维护的噩梦。
最后,Solidity 合约通常非常简单,而导入文件可能会增加不必要的复杂性、成本和文件管理。
尽管如此,我们认为值得探索各种可能性,即使只是为了拒绝它们。
Solidity 类特性
Solidity 已经有很多与现代 OOP 语言非常不同的特性,如:合约、可支付账号(payable account);执行的 Gas 消耗;永久存储;全局执行等等。
然而,合约不是类,因为Solidity有函数调度程序和其他开销,调用其他合约的函数是非常昂贵的。我在另一篇文章中有提到过“Solidity 函数的 Gas 消耗 ”。
Solidity 提供了哪些功能来实现将代码和数据封装在类里呢?
下面我们将开始探讨:
1) 导入文件
2) 合约继承
3) 将库附加到结构体
在所有这些功能中,数据和函数都可以使用类似类的点符号。例如:myClass.myFunction(myArgument)
。在某些情况下,也可以不用指定类。
1)导入文件
有一下几种情况,我们应该作为一个单独的实体文件保存,然后再导入它们,例如:
1.1) 其他合约
在 Solidity 中,合约有可能创建其他合约。除了为测试而创建的临时合约外,那些其他合约似乎很有可能是在不同的文件中被定义:
import "OtherContract.sol";
contract MyContract ... {
OtherContract otherContract;
constructor(...) public ... {
otherContract = new OtherContract(...);
}
...
}
1.2) 继承的合约
在 Solidity 中,也可以继承合约。并且,除了为测试而创建的临时合约外,继承的合约似乎很有可能被重复使用,所以在一个单独的文件中定义很重要,在下面(2)会进一步探讨。
1.3)库
在 Solidity 中也可以创建库,库函数可以是外部或内部的。任何包含外部函数的库大概都是为了被其他合约重用,所以应该在一个独立的文件中定义。
import "SortLibray.sol";
contract MyContract ... {
MyStruct data;
...
function sortData(...) internal ... {
SortLibrary.sort(data);
}
...
}
包含内部函数的库将与合约的字节码一起被打包。这些将在(3)中讨论。
2) 合约继承
在 Solidity 中,有两种方式可以有效地提供类特性,一种是继承基础合约。
被继承的基础合约是一个普通合约,包含数据和可以作用于这些数据的函数,但通常是不完整的,或者说只是完整合约的一个片段。恰当的文件命名习惯是很有用,可以清楚知道哪些合约是作为可继承的基础合约。
我们还可以把继承当做对象组合来使用,这在下面的例子中会讲到。
3) 将库附加到结构体
这是另一种有效提供类特性的方式,这种方式是创建一个结构体并附加一个库,库中的函数接受该结构体。这就是将一个库附加到一个类型(通常是一个结构体)。
在希望使用该类的合约中,声明了结构体的变量,并可提供结构体作为参数来调用库函数。
Solidity 提供了一个编译器指令,以支持使用点符号调用库函数,这就是using for
( using library for struct)。这个功能也可以用于扩展标准类型,例如, using NumbersLib for uint
。
看看下面的例子。
一些使用 Solidity 类特性的例子
我们用一个简单的合约来演示类特性技术。
这个版本的合约,使用一个叫做ContractOwner
的基础合约和一个叫做Partners
的组件类。
import "ContractOwner.sol";
import "Partners.sol";
co...
剩余50%的内容订阅专栏后可查看
- 单篇购买 3学分
- 永久订阅专栏 (90学分)
- 发表于 2021-09-22 16:02
- 阅读 ( 830 )
- 学分 ( 79 )
- 分类:Solidity
- 专栏:全面掌握Solidity智能合约开发
评论