# 智能合约开发-1

By [vim](https://paragraph.com/@vimyang-2) · 2022-04-03

---

lesson-1-hello
--------------

几个知识点

*   msg是内部变量，不能使用
    
*   函数的参数变量，不需要存储，因此可以指定类型之后，添加\`\`\`memory\`\`\`关键词
    
*   如果函数返回内部变量，只读，可以使用关键词\`\`\`view\`\`\`
    
*   返回变量的关键词是\`\`\`returns\`\`\`，而不是\`\`\`return\`\`\`
    

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    contract Hello {
        string public name;
        
        function setName(string memory name_) public{
            name = name_;
        }
            
        function getName() public view returns (string memory){
            return name;
        }
    }
    

使用msg的时候，出现如下的编译警告

    Warning: This declaration shadows a builtin symbol.
    --> contracts/lesson/lesson-1-hello.sol:7:5:
    |
    7 | string public msg;
    | ^^^^^^^^^^^^^^^^^
    

lesson-2-unitEth
----------------

以太坊中单位的对应关系

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    contract EthUint {
        uint public oneWei = 1 wei;
        uint public oneGwei = 1 gwei;
        uint public oneEth = 1 ether;
        
        function testOneWei() public view returns (bool) {
            return oneWei == 1;
        }    
        
        function testOneGgei() public view returns (bool) {
            return oneGwei == 1 * 10**9;
        }    
        
        function testOneEth() public view returns (bool) {
            return oneEth == 1 * 10**18;
        }
    }
    

也可以参考网站：[https://eth-converter.com/](https://eth-converter.com/)

![](https://storage.googleapis.com/papyrus_images/b42fc5838c741466d706591fa783ca7d41ee1aa037eeb8174268be7c79633f9c.png)

### lesson-3-fun-visibility

函数的可见性严格排序

    // private internal external public 
    

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    // private internal external public 
    
    contract funVisibility {
        uint age;
        
        function funPublic() public view returns (uint){
            return age;
        }
        
        function funExternal() external view returns (uint){
            return age;
        }
        
        function funInternal() internal view returns (uint){
            return age;
        }
        
        function funPrivate() private view returns (uint){
            return age;
        }
        
         function testFun() public view returns(uint) {
            // return funPublic(); // ok 
            // return funExternal(); // not ok
            //  return funInternal(); // ok
            return funPrivate(); // ok
        }
    }
    
    
    contract subFunVisibility is funVisibility{
        function testParentFun() public view returns(uint) {
            // return funPublic(); // ok 
            // return funExternal(); // not ok
            // return funInternal(); // ok
            // return funPrivate(); // not ok
        }
    }
    

扩展阅读：[https://tsaiyee.com/blog/2018/01/07/solidity-external-public-best-practices/](https://tsaiyee.com/blog/2018/01/07/solidity-external-public-best-practices/) 【Solidity中的external与public使用最佳实践】

lesson-4-inherit
----------------

[![]({{DOMAIN}}/editor/youtube/play.png)](https://www.youtube.com/watch?v=gg5i57z6Hqo)

继承知识点

*   继承的语法是子类 is 父类
    
*   如果需要重写父类函数，父类定义需要使用virtual，子类需要使用pure override
    
*   如果父类构造函数有参数，子类定义的时候，也需要为父类指定构造函数的参数
    

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    // private internal external public 
    
    contract Parent {
        uint age;
        
        constructor(uint age_){
            age = age_;
        }
        
        function getAge() public view returns (uint){
            return age;
        }    
        
        function getDesc() public view virtual returns (string memory){
            return "Parent";
        }
    }
    
    
    contract Son is Parent(55){
        // can call getAage fun
        
        function getDesc() public pure override(Parent) returns (string memory){
            return "Son";
        }
    }
    

扩展阅读：[https://medium.com/taipei-ethereum-meetup/solidity-weekly-11-70c5208a3bf1](https://medium.com/taipei-ethereum-meetup/solidity-weekly-11-70c5208a3bf1) 【pure 跟 view 的区别】

更正確的講，如果一個 function 不會改變到合約的 state，就可以加 modifier constant 在 returns 前面，因此在 web3.js 就可以用 call() 來呼叫該 function， 而不需要用 sendTransaction() 來呼叫。

到了 solc 0.4.17, 更把 constant 細分為 view 或 pure 兩種，只是程度上的不同。

view 一般來說，就用來取代 constant, 跟 compiler 説，該 function 不會對 storage state 有任何變動。(但會進行讀取, 所以 constant 改名為 view，更為恰當)

    string greeting;
    function SayHello() public view returns(string says) {
            return greeting;
    }
    

pure 定義該 function 連讀 storage state 都沒有。有人舉了一個誇張的例子如下：(它跟合約的所有 states 都無關, 可以加 modifier pure)

    function returnTrue() public pure returns(bool response) {
        return true;
    }
    

lesson-5-multiInherit
---------------------

[![]({{DOMAIN}}/editor/youtube/play.png)](https://www.youtube.com/watch?v=rTZwYsn49Bw)

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    // private internal external public 
    
    contract A {
        uint age;
        
        constructor(uint age_){
            age = age_;
        }
        
        function getAge() public view returns (uint){
            return age;
        }    
    }
    
    contract B {
        string name;
        
        constructor(string memory name_){
            name = name_;
        }
        
        function getNmae() public view returns (string memory){
            return name;
        }    
    }
    
    
    contract C is A, B{
        constructor()A(10) B ("hello"){
            
        }
    
    }
    
    
    
    contract D is A, B{
        constructor(uint age_, string memory name)A(age_) B (name){
            
        }
    
    }
    

lesson-6-event
--------------

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    contract Event {
        event Log(address sender, string msg );
        
        function trancfer() public{
            emit Log(msg.sender, "This is 1 mag");
            emit Log(msg.sender, "This is 2 mag");
            emit Log(msg.sender, "This is 3 mag");
        }
    }
    

lesson-7-globalVal
------------------

[![]({{DOMAIN}}/editor/youtube/play.png)](https://www.youtube.com/watch?v=tiG0PX2Uxd0)

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    contract Hello {
        event Log(address, uint);
        
        function getGasInfo() public view returns(uint, uint){
            return (tx.gasprice, block.gaslimit);
        }
        
        function getMagInfo () public payable {
           emit Log(msg.sender, msg.value);
        }
    }
    

lesson-8-errorHandle
--------------------

[![]({{DOMAIN}}/editor/youtube/play.png)](https://www.youtube.com/watch?v=BrDXz9En58c)

参数尽量提前检查，多执行代码，会增加gas费

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    contract ErrorHandle {
        int public balance = 0;
        
        function add(int trans_num) public{
            require(trans_num >= 0, "The trans num should big than 0");
            
            // int old_balance = balance;
            balance += trans_num;
            
            //assert(balance >= old_balance);
            
            // if(balance < old_balance){
            //     revert("error");
            // }
        }
    }
    

lesson-9-array
--------------

需要注意的是，array的del函数并没有删除数据，只是把数据进行了清空

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    // array 
    // push pop del length
    
    contract Array {
        uint[] public array1;
        uint[3] public array2;
        uint [] public arrar3 = [1,2,3];
        
        function push(uint val) public{
            array1.push(val);
        }
            
         
        function pop() public{
            array1.pop();
        }
        
        function length() public view returns(uint){
            return array1.length;
        }
            
        function del(uint index) public{
            // param check
            delete array1[index];
        }
        
        function test() public{
            array1.push(1);
            array1.push(2);
            array1.push(3);
            array1.push(4);
            
            assert(length() == 4);
            
            pop();
            assert(length() == 3);
            assert(array1[2] == 3);
            
            del(2);
            assert(length() == 3);
            assert(array1[2] == 0);
        }
    }
    

lesson-10-map
-------------

需要注意的是

*   map的del函数，也只是把数据清空而不会把数据真正的删除
    
*   map没有遍历函数，如果希望遍历，可以添加一个辅助的数组
    

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    contract Map {
        mapping(address => uint)  public MyMap;
        
        function setMap(address add_, uint num) public{
            MyMap[add_] = num;
        }
            
        function delMap(address addr_) public{
            delete MyMap[addr_];
        }
            
        function getlMap(address addr_) public view returns (uint){
            return MyMap[addr_];
        }
    }
    

lesson-11-struct
----------------

注意事项

*   外部string参数使用memory修饰，int、bool等类型无需
    
*   内部结构体需要使用storage修饰
    

    // SPDX-License-Identifier: GPL-3.0
    
    pragma solidity 0.8.4;
    
    contract Struct {
        struct Todo{
            string task;
            bool complete;
        }
        
        Todo [] public todo_list;
        
        function add(string memory _task) public {
            // Todo memory todo = Todo(_task, false);
            
            // Todo memory todo = Todo({
            //     task: _task,
            //     complete : false
            // });
            
            Todo memory todo;
            todo.task = _task;
            todo.complete = false;
            
            todo_list.push(todo);
        }
        
        function get(uint index) public  view  returns (Todo memory){
            return todo_list[index];
        }
        
        function getEle(uint index) public  view  returns (string memory, bool){
            Todo storage todo =  todo_list[index];
            return (todo.task, todo.complete);
        }
    }

---

*Originally published on [vim](https://paragraph.com/@vimyang-2/1)*
