Solidity初学

发布时间 2023-12-05 20:21:48作者: 芜光

https://www.youtube.com/watch?v=xv9OmztShIw&list=PLO5VPQH6OWdVQwpQfw9rZ67O6Pjfo6q-p

helloworld

// SPDX-License-Identifier: MIT 
// 如果没有上面的license就会出现黄色warning, 挺难看的..
pragma solidity ^0.8; // 指定solidity编译版本, 带了^号说明要在该版本(0.8)以上, 不加的话就是指定在(0.8)版本
contract HelloWorld {
    /**
     * @dev Prints Hello World string
     */
    function print() public pure returns (string memory) {
        // public是指明这个函数/变量能在合约部署后能够访问, 所以后面我能执行这个function
        return "Hello World!";
    }
}

编译(compile)和部署(deploy)

Remix的环境做得非常友好了, 它还自带了Remix VM测试用账号. 在Environment下设置. 我用的是之前配置好的MetaMask账号. 这两个是有区别的.

  • 前者是部署在仅在浏览器内运行的本地区块链上, 一般不用等什么交易确认的, 非常快
  • 后者是部署到MetaMask连接到的mainnet上. 我用的是holesky测试网, 所以在测试网上会有我的交易记录. 我还需要等区块链确认了我才能用我部署的合约.
    合约部署申请
    申请成功
    交易记录
    环境
    部署完成后, Deploy下会有显示, 如下图.
    helloworld执行结果

(常见的)数据类型

Java类似, solidity数据类型是分为了值类型和引用类型.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
contract ValueTypes {
    bool public b = true;
    uint public u = 123; // uint = uint256 0 to 2**256 - 1
                         //        uint8 0 to 2**8 - 1, and uint16...
    int public i = -123; // int = int256 -2**255 to 2**255 -1, and int128...
    int public minInt = type(int).min;
    int public maxInt = type(int).max;
    // address和bytes32都是格式不对就立马报错. 
    // 后者跟加密算法keccak256有关.
    address public addr = 0x02342Ea564978abBf379b377eE58A0d7142121d4;
    bytes32 public b32 = 0x000000000000000000000000000000000000000000000000000000000000007b;
}

函数(function)

external表示部署合约后可以调用这个函数, pure表示这个函数是只读的, 不会向区块链写入其它内容.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
contract FunctionInfo {
    function add(uint x, uint y) external pure returns(uint){
        return x + y;
    }
    function sub(uint x, uint y) external pure returns(uint){
        return x - y;
    }
}

编译, 部署后执行. 注意solidity可以处理溢出错误是在它0.8版本之后. 我在执行sub的时候是先用了参数2,3, 溢出后就是图中的内容.
加减法执行结果

变量类型

视频说得有点复杂, 实际上可以理解为作用范围和生命周期的不同.

state variable

state variable在区块链上存储的变量. 定义在合约内部, 函数外部.

local variable

局部变量相对于状态变量, 是定义在函数内部.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
contract StateVariable {
    uint public stateval = 123;
    function foo() external  {
        uint localval = 123;
        stateval = localval + stateval + 10;
    }
}

img
state variablelocal variable作用就如上所示了. state variable会一直存在, 而local variable在函数执行完之后就被销毁了.

global variable

一般是存储区块链交易/事务或者账户地址之类的.
view关键字修饰的函数可以从state variableglobal variable读取数据, pure函数不行.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
contract GlobalVariables {
    function globalVars() external view returns(address, uint, uint){
        address addr = msg.sender; // 调用此函数的地址
        uint timestamp = block.timestamp; // uinx时间戳
        uint num = block.number; // 当前block的编号
        return (addr, timestamp, num);
    }
}

img

view 和 pure

其实用错了的话编译器是有提示的, 就不多说了.
img
img

简单案例: Counter

// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
contract Counter {
    uint public count;
    function inc() external {
        count += 1;
    }
    function dec() external {
        count -= 1;
    }
}

img