在试图理解继承的OpenZeppelin合同时,在导入OpenZeppelin的计数器库:https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol之后,我无意中发现了行OpenZeppelin。
我意识到这种使用库的方式在OpenZeppelin GitHub上的源代码中是“建议”的。但是,我不明白为什么。快速研究告诉我,using关键字用于允许特定类型使用库中的函数,就好像它们是来自这些类型(https://medium.com/coinmonks/soliditys-using-keyword-c05c18aaa088)的属性一样。
我本以为输入图书馆就足够了。如果有人能向我解释这背后的编码逻辑,那将对我有很大的帮助。谢谢。
发布于 2021-12-16 17:12:24
Counters是一个库。
当我们说using A for B时,这意味着我们将库A中的每个函数附加到B类型中。
库是降低气体费用的一种有效方法,因为它们只在特定的地址部署一次,其代码被各种契约重用。
所以回到问题上。Counter是Counters库中的结构化数据类型。
这是它的源代码:
library Counters {
struct Counter {
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}当您说using Counters for Counters.Counter时,这意味着我们将Counters库中的所有函数(如current()或increment() )分配给Counter结构。
当您调用这些函数时,这些函数的第一个参数是类型本身,在本例中是Counter结构。
因此,在下面的代码中,当我们调用clock.current()时,它将作为current()函数的第一个参数传递clock,这是一个结构。
using Counters for Counters.Counter;
Counters.Counter clock;
clock.current() // results to 0发布于 2021-09-27 14:27:33
Counters.Counter是由库定义的结构,它只包含一个uint256 (名为_value)。
如果您查看这个库,您会发现每个函数并不只是调用传递的计数器并增加它--相反,它们调用计数器的_value属性,然后增加它。
解决这个问题的原因是,我们希望能够在uint256s上使用计数器,而不影响合同中的所有uint256s。
因此,当您想要增加uints时,您可以使用Counters.Counter作为uints的代名词。
发布于 2021-09-28 06:28:59
表达式using Library for type允许我们在使用库中的某些函数时使用语法糖。它不是必需的,但它使契约更加可读性。
例如,SafeMath有
library SafeMath {
function add(uint256 a, uint256 b) public pure returns (uint256) {
// some unimportant details here
}
}然后你可以用在合同里
function (uint256 x, uint256 y) public pure returns (uint256) {
returns add(x, y);
}您可以添加using SafeMath for uint256
function (uint256 x, uint256 y) public pure returns (uint256) {
returns x.add(y);
}它本身并不多,但是它的语法接近于从一个对象调用一个方法。
https://ethereum.stackexchange.com/questions/97186
复制相似问题