我在solidity中玩可见性和映射,发现了一些我试图更好地理解的东西。一个是内部知名度,另一个是公众。我部署了它们,得到了两个不同的工作结果。
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract Marketplace {
mapping (uint => string) internal products;
function writeproduct(uint _index, string memory _product) public{
products[_index] = _product;
}
function readproduct(uint _index) public view returns(string memory) {
return products[_index];
}
}
带有内部可视的代码图片
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract Marketplace {
mapping (uint => string) internal products;
function writeproduct(uint _index, string memory _product) public{
products[_index] = _product;
}
function readproduct(uint _index) public view returns(string memory) {
return products[_index];
}
}
图片显示代码与公众能见度
看到这些之后,我决定删除readproduct函数,看看会发生什么,这就是我得到的。请帮我更好地理解。
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract Marketplace {
mapping (uint => string) public products;
function writeproduct(uint _index, string memory _product) public{
products[_index] = _product;
}
}
这就是我得到的。在删除readproduct功能后,它仍然工作
如果可见性为public
,solidity将为公共变量分配一个getter函数。这就是您看到getter函数的原因。但是在映射和数组的情况下,getter函数不会返回整个对象。相反,您必须为映射输入一个键,为数组输入索引,然后才能获得单个项。
在internal
可见性的情况下,不能从外部访问这些变量。可以从当前合同或从当前合同派生的子合同中的函数访问它们。
当可见性是内部的时,您不能访问变量,您必须创建一个getter函数来访问它。
在您的案例中,当products
的可见性为internal
时,您创建了一个readproduct
函数来访问其值。但当可见性为public
时,您不需要getter函数——您可以直接访问它,solidity编译器会为您制作一个。
但特别是对于通过hardhat中的脚本访问它们的映射,无论可见性如何,都必须有一个getter函数,但它在remix或etherscan上都是可见的(如果合同得到验证,则是可见的(。这就是我所经历的。