一、工厂模式创建合约
// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;
//站点
contract Station {
//站点名称
string private name;
//站点位置
string addr;
//站点人员数量
uint16 count;
//构造函数
constructor(string memory _name, string memory _addr, uint16 _count) {
name = _name;
addr = _addr;
count = _count;
}
function getStationInfo() public view returns (string memory, string memory, uint16) {
return (name, addr, count);
}
}
//站点工厂
contract StationFactory {
//状态变量 - 存储所有已创建的站点
address[] stations;
// 创建站点工厂
function createStation(string memory _name, string memory _addr, uint16 _count) external {
Station station = new Station(_name, _addr, _count);
stations.push(address(station));
}
//获取所有站点工厂
function getStationAll() external view returns (address[] memory) {
return stations;
}
}
第1步:部署合约 - 选择StationFactory合约部署;
第2步:创建合约,调用StationFactory合约中的createStation方法
第3步:选择合约“Station”, 再点击“At Address”,终于出来梦寐已久的防疫站点合约了,查看下在工厂合约中增加的防疫站点,没错,就是它了。
第4步:点getStationAll按钮,就返回刚刚提交的记录
二、调用其他合约,通过address
pragma solidity^0.6.0;
contract C1{
string private name;
function getName() external view returns (string memory) {
return name;
}
function setName(string calldata _name) external {
name = _name;
}
}
contract C2{
C1 c;
constructor(address addr) public {
//部署时填写被调用合约C1的地址
c = C1(addr);
}
function getName() external view returns (string memory) {
return c.getName();
}
function setName(string calldata _name) external {
c.setName(_name);
}
}
c2部署时,需要填c1合约地址
三、通过接口管理调用的合约,主-从模式
主合约地址永恒不变
从合约地址可以更改或设置多个 (如下,c1、c2)
从合约地址可以通过主合约地址获取
pragma solidity^0.6.0;
//接囗IC
interface IC {
//获取名称
function getName() external view returns(string memory);
//设置名称
function setName(string calldata _name) external;
}
//合约C1实现接囗IC
contract C1 is IC {
//状态变量
string name;
//获取名称
function getName() external view override returns(string memory){
return name;
}
//设置名称
function setName(string calldata _name) external override{ // calldata和external一起使用
name = _name;
}
}
//合约C2实现接囗IC
contract C2 is IC {
//状态变量
string name;
//获取名称
function getName() external view override returns(string memory){
return name;
}
//设置名称
function setName(string calldata _name) external override{
name = _name;
}
}
//合约C通过合约地址调用C1或C2
contract C {
//状态变量,接囗IC
IC c;
//设置合约地址
function setICAddress(address addr) public {
c = IC(addr);
}
//通过接囗调用 获取名称
function getName() public view returns (string memory) {
return c.getName();
}
//通过接囗调用 设置名称
function setName(string memory _name) public {
c.setName(_name);
}
}
四、代理模式
代理模式借鉴的是回调思想,只关注合约地址,并不关注合约的ABI。
合约想要收取外部账户给的以太(钱)时,要使用fallbak或receive。
未使用fallbak或receive时,合约接收钱,如下例代码所示:
pragma solidity^0.6.0;
contract C1{
function getContractAccountBalance() public view returns (uint256) {
return address(this).balance;
}
//fallback表示此合约能够接收外部账户转账的钱
fallback() external payable {
}
}
contract C{
function transfer(address payable _to, uint256 _value) public payable{
require(msg.value >= _value, "转账金额要充足"); // msg.value设置的wei数大于 _value
_to.transfer(_value);
}
}