PS. 本人才疏学浅,欢迎交流指正。
使用合约部署合约
下面我们将尝试通过一个合约部署另一个合约。
创建一个StorageFactory.sol文件。将之前写好的SimpleStorage合约复制进去。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
contract SimpleStorage {
uint256 favoriteNumber;
mapping(string => uint256) public nameToFavoriteNumber;
function store(uint256 _favoriteNumber) public {
favoriteNumber = _favoriteNumber;
}
function retrieve() public view returns (uint256) {
return favoriteNumber;
}
struct People {
uint256 favoriteNumber;
string name;
}
People[] public people;
function addPerson(string memory _name, uint256 _favoriteNumber) public {
people.push(People(_favoriteNumber, _name));
nameToFavoriteNumber[_name] = _favoriteNumber;
}
}
然后声明一个StorageFactory合约,代码如下。
contract StorageFactory {
}
在StorageFactory合约中声明一个SimpleStorage类型的变量,定义createSimpleStorageContract方法,通过其中的new关键字,我们部署一个SimpleStorage合约。
contract StorageFactory {
SimpleStorage public simpleStorage;
function createSimpleStorageContract () public {
simpleStorage = new SimpleStorage();
}
}
将要部署的合约切换为StorageFactory,如下,进行部署。
部署成功后,点击createSimpleStorage按钮,调用createSimpleStorageContract方法,该方法会部署一个SimpleStorage合约。
调用成功后,部署好的SimpleStorage合约的地址会赋值给变量simpleStorage,点击simpleStorage按钮查看该变量的值,可以看到部署好的合约地址。
引入外部合约文件
为了避免代码重复和单个sol文件过于冗长,可以从其它sol文件中引入合约。
删除前面复制到StorageFactory.sol的SimpleStorage合约代码,添加引入外部合约到代码如下。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "./SimpleStorage.sol";
contract StorageFactory {
SimpleStorage public simpleStorage;
function createSimpleStorageContract () public {
simpleStorage = new SimpleStorage();
}
}
调用外部合约的方法
通过调用Contract类型变量内部的方法
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "./SimpleStorage.sol";
contract StorageFactory {
SimpleStorage[] public simpleStorageArray;
function createSimpleStorageContract () public {
SimpleStorage simpleStorage = new SimpleStorage();
simpleStorageArray.push(simpleStorage);
}
function sfStore(uint256 _simpleStorageIndex, uint256 _simpleStorageNumber) public {
SimpleStorage simpleStorage = simpleStorageArray[_simpleStorageIndex];
simpleStorage.store(_simpleStorageNumber);
}
function sfGet(uint256 _simpleStorageIndex) public view returns(uint256) {
// SimpleStorage simpleStorage = simpleStorageArray[_simpleStorageIndex];
// return simpleStorage.retrieve();
return simpleStorageArray[_simpleStorageIndex].retrieve();
}
}
使用上一节的操作,我们同样可以通过调用createSimpleStorageContract方法部署SimpleStorage合约。
合约的继承
使用关键字is来继承合约,代码如下。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "./SimpleStorage.sol";
contract ExtraStorage is SimpleStorage {
}
部署后可以看到ExtraStorage合约拥有SimpleStorage合约的所有方法,如下图。
合约的重载
有时我们想重写某些继承得来的方法,这种行为称为“重载”。实现合约方法的重载需要两步:
- 进行重载的方法带上关键字
override,在这里我们让ExtraStorage合约中的store方法进行重载,代码如下。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "./SimpleStorage.sol";
contract ExtraStorage is SimpleStorage {
// child function need to be 'override'
function store(uint256 _favoriteNumber) public override {
favoriteNumber = _favoriteNumber + 5;
}
}
- 被重载的方法带上关键字
virtual,这里被重载的使SimpleStorage合约中的store方法,代码如下。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
contract SimpleStorage {
// ...
// parrent function need to be 'virtual'
function store(uint256 _favoriteNumber) public virtual {
favoriteNumber = _favoriteNumber;
}
// ...
}
部署ExtraStorage合约后分别调用store和retrieve方法,可以看到store方法的效果已经是重载之后的逻辑了,如下图。