使用Remix入门Solidity智能合约(二)

462 阅读2分钟

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.solSimpleStorage合约代码,添加引入外部合约到代码如下。

// 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合约的所有方法,如下图。

合约的重载

有时我们想重写某些继承得来的方法,这种行为称为“重载”。实现合约方法的重载需要两步:

  1. 进行重载的方法带上关键字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;
    }
}
  1. 被重载的方法带上关键字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合约后分别调用storeretrieve方法,可以看到store方法的效果已经是重载之后的逻辑了,如下图。