工厂模式创建合约&合约互调

本文介绍了智能合约设计中的几种模式:工厂模式用于创建和管理站点合约;调用其他合约展示了如何通过合约地址交互;接口管理模式允许主合约动态调用不同从合约;代理模式则利用回调思想实现合约间的资金转移。这些模式展示了智能合约的灵活性和交互性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、工厂模式创建合约

// 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);
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端段

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值