本文介绍了Solidity中的继承概念,包括如何使用is
关键字实现合约继承。文章详细讲解了virtual
和override
关键字在函数重写中的作用,以及internal
关键字在控制函数可见性方面的应用。最后,通过OpenZeppelin的Ownable合约示例,展示了继承在实际开发中的应用,例如权限控制。
欢迎来到 Solidity 开发的最后一集。就像我说的,区块链开发不仅仅是 Solidity 和智能合约,但它只是其中的一个关键部分。“如何成为区块链开发者”系列也会在此之后继续进行。
所以,之前我们稍微谈了下复杂数据类型。现在是我们谈论继承的时候了。对于那些不知道编码中继承意味着什么的人来说,它基本上是拥有第一个接口并创建属于第一个接口的第二个接口。这只是一场父母和孩子的游戏。
看看上面的代码。我在一个界面中有两个不同的合约。我定义了一个名为 amount 的变量,并且我也有一个函数来增加它的值。在我完成 ParentContract 之后,我定义了另一个名为 ChildContract 的合约。请注意我是如何在我的合约之间声明继承的。当我想要一个合约从另一个合约派生内容时,我会说
contract DerivedContract is DerivenContract {}
一个非常简单的用法,真的。但它到底做了什么?我们现在将部署我们的合约,但我希望你注意一件事。
在值部分的下方,有一个名为“contract”的部分。 这是你选择要部署哪个合约的部分。 我们现在选择 ChildContract 并部署它。
看到了吗? 即使我在 ChildContract 中什么也没做,它也从 ParentContract 中派生了它的变量和函数。 这就是继承的意义!
现在,我们必须再多谈谈函数。
现在,这里有一个真正的交易。 我们有两个新的关键字,virtual 和 override。 我在这里所做的基本上是为了改变函数的工作方式。
1- 我在父合约中有一个函数。 我将其标记为“virtual”,以便以后可以被子合约更改。
2- 我在 ChildContract 中声明了一个具有相同名称 (increaseAmount) 的函数,并且我将其标记为 override。 所以,我们将其标记为 override 的原因是告诉 Solidity 我们没有声明一个新函数,我们只是在更改 ParentContract 中已经存在的函数。
3- 然后我改变了这个函数的工作方式。
让我们部署我们的两个合约并点击一次增加数量按钮。
ParentContract
ChildContract
看到了吗? 同一个函数在每个合约中增加了不同的数量。 那是因为我们改变了 increaseAmount 函数在 ChildContract 中的工作方式。 但是,如果我有时想使用 ParentContract 的版本,而有时想使用 ChildContract 的版本呢?
所以,父版本的 returnString 函数将返回“I am the Parent”,而子版本将返回“I am the Child”。 我还定义了另一个名为 print message 的函数。 如果 isChild_ 值为 true,则该函数将调用 returnString(),这是子版本。 如果 isChild_ 为 false,则该函数将从其父合约调用 returnString()。 因此,使用关键字 super,你可以访问你的 ChildContract 从中派生的 ParentContract 的数据。
Virtual 和 Override 对于我们理解来说非常重要。 它们确实是继承的支柱。 顺便说一句,你可能想知道我们在哪里以及为什么使用继承,你完全有权利这样做。 我将在最后向你展示一个例子。
现在,这是我想谈的最后一件事:函数可见性。 我们谈论了 public、private 和 external,但我们从未真正谈论过“internal”。 我告诉过你我将在继承这一集中解释它:) internal 函数基本上只允许子合约访问和调用该函数。 让我们做一个例子。
在上面的代码中,你可以看到我已将 increaseAmount 标记为 internal。 你也可以看到我可以使用 ChildContract 的 increaseAmountTwice 函数来调用它。 让我们部署我们的两个合约。
正如你所看到的,我在 ParentContract 中标记为 internal 的 increaseAmount 函数已停止使用。 你不能以用户身份与它交互,你只能在子合约中调用该函数。 这就是 internal 的全部意义。
现在我们已经完成了上下文,让我们看看我们在哪里使用继承。 假设你刚刚在 github 中找到了一份合约,你非常非常喜欢它。 你想使用该合约并添加一些其他内容。 你只需将该合约作为父合约,然后使用你编写的另一个智能合约派生其中的所有内容。
有一个名为 OpenZeppelin 的开源智能合约开发协议。 这些合约由高级开发人员开发,主要用于以安全的方式处理智能合约开发。 现在,我只想导入他们的一份合约并将其用作我自己的合约。
我希望你打开这个链接并转到 OpenZeppelin 的“Ownable”合约。 这是我们将用作父合约的合约。
Ownable
我们想要使用此合约中的一个 modifier。“onlyOwner”modifier。它基本上是检查合约的所有者是否与调用该函数的人相同。现在让我们导入此合约作为我们的父合约。
这样,你已经学会了导入合约的方式。现在我导入了 Ownable 合约,就像我将它写在我的界面中一样。我现在可以创建另一个合约并从“Ownable”派生项目。请注意,我在调用 Ownable 合约时传递了 msg.sender 作为参数。这是因为 Ownable 合约中有一个构造函数,它接受一个地址来初始化所有者。
myContract 供人们在合约内部署 eth,withdraw() 供所有者提取他想从合约中提取的尽可能多的资金。
1- 让我们使用第一个帐户地址部署我们的 myContract。
2- 然后我们切换到第二个帐户并部署 10 eth。
3- 现在让我们切换到我们的第三个帐户并尝试提取 5 eth。
你应该会看到这个错误。请注意“Error provided by the contract: OwnableUnauthorizedAccount”。我们无法提取,因为第三个不是合约的所有者,第一个是。
4- 让我们切换回我们的第一个帐户并提取 5 eth。
你成功了!我们成功地使用了来自 OpenZeppelin 的 github 的 Ownable 合约的上下文。现在你了解了有关 Solidity 基础知识的所有信息。是时候转向其他目标了。在下一集“如何成为区块链开发者”中再见!
- 原文链接: coinsbench.com/how-to-be...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!