对应崔棉大师 26-40课程
https://www.bilibili.com/video/BV1yS4y1N7yu/?spm_id_from=333.788&vd_source=c81b130b6f8bb3082bdb42226729d69c

部署合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7; contract TestContract1{
address public owner = msg.sender; function setOwner(address _owner) public{
require(owner== msg.sender,"not owner");
owner = _owner;
} } contract TestContract2{
address public owner = msg.sender;
uint public value = msg.value;
uint public x;
uint public y;
constructor(uint _x,uint _y){
x = _x;
y = _y;
}
} contract Proxy{
function deploy() public payable returns(address addr){
//强转为address类型 否则报错 不能进行隐式转换
// owner地址为Proxy地址
addr = address(new TestContract1());
return addr;
}
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Proxy {
    event Deploy(address); //事件
    fallback() external payable {} //可能接受主币要有回退函数
    receive () payable external {} //
    function deploy(bytes memory _code) external payable returns (address addr) {
        assembly { //内联汇编
            // create(v, p, n)
            // v = amount of ETH to send 发送eth金额
            // p = pointer in memory to start of code 合约二进制编码,再偏移20
            // n = size of code 合约二进制编码长度
            addr := create(callvalue(), add(_code, 0x20), mload(_code)) //隐式返回
        }
        // return address 0 on error
        require(addr != address(0), "deploy failed"); //确实部署成功返回地址不为0
        emit Deploy(addr);
    }
    function execute(address _target, bytes memory _data) external payable {
        //_target目标地址
        (bool success, ) = _target.call{value: msg.value}(_data);
        require(success, "failed");
    }
}
contract TestContract1 {
    address public owner = msg.sender;
    function setOwner(address _owner) public {
        require(msg.sender == owner, "not owner");
        owner = _owner;
    }
}
contract TestContract2 {
    address public owner = msg.sender;
    uint public value = msg.value;
    uint public x;
    uint public y;
    constructor(uint _x, uint _y) payable {
        x = _x;
        y = _y;
    }
}
contract Helper {
    function getBytecode1() external pure returns (bytes memory) {
        bytes memory bytecode = type(TestContract1).creationCode;// 获取二进制编码
        return bytecode;
    }
    function getBytecode2(uint _x, uint _y) external pure returns (bytes memory) {
        bytes memory bytecode = type(TestContract2).creationCode;// 获取二进制编码
        return abi.encodePacked(bytecode, abi.encode(_x, _y)); //构造函数编码后拼接
    }
    function getCalldata(address _owner) external pure returns (bytes memory) {
        return abi.encodeWithSignature("setOwner(address)", _owner); //构造函数call编码
    }
}
 

存储位置

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract DataLocations {
    struct MyStruct{
        uint foo;
        string text;
    }
    mapping(address => MyStruct) public MyStructs;
    function examples(string memory  _x,uint[] calldata _y) external{
        MyStructs[msg.sender] = MyStruct({foo:123,text:"bar"});
        //状态变量
        MyStruct storage write = MyStructs[msg.sender];
        write.text = "foo";
        //局部变量
        MyStruct memory read = MyStructs[msg.sender];
        read.foo = 456;
        //节省gas:calldata传递参数时候不需要重新赋值 memory传递参数需要重新赋值
        calldata_fun(_x,_y);
    }
    function calldata_fun(string memory  _x,uint[] calldata _y )  private pure returns(uint,string memory){
        uint y = _y[0];
        string memory x = _x;
        return (y,x);
    }
}

简单存储


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract SimpleStorage {
    string public text;
    // transaction cost 27359 gas 交易消耗gas (包括execution cost)
    // execution cost   5851 gas evm执行消耗gas
    function memory_set(string memory _input) external{
            text = _input;
    }
    // transaction cost 26855 gas
    // execution cost   5347 gas
    //节省gas:calldata比memory 执行gas少
    function calldata_set(string calldata _input) external{
            text = _input;
    }
}

待办事项列表


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract ToDoList {
    struct Todo{
        string text;
        bool completed;
    }
    Todo[] public todos;
    function create(string calldata _text) external{
        todos.push(Todo({
            text:_text,
            completed:false
        }));
    }
    function updateText(uint _index,string calldata _text) external{
        //节省gas:单个参数更新下面的方式
        todos[_index].text = _text;
        // 节省gas:多个参数更新下面的方式
        // Todo storage t = todos[_index];
        // t.text = "a";
        // t.text = "b";
        // t.text = "c";
        // t.text = "d";
    }
    function get(uint _index) external view returns(string memory,bool){
        //从storage到return复制一次
        //Todo storage todo = todos[_index];
       
        //storage到memory到memory 复制两次
        Todo memory todo = todos[_index];
        return (todo.text,todo.completed);
    }
    function toggleCompleted(uint _index) external {
        todos[_index].completed = !todos[_index].completed;
    }
}

事件


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Event {
    // Event declaration
    // Up to 3 parameters can be indexed. 一个时间最多定义三个索引
    // Indexed parameters helps you filter the logs by the indexed parameter
    event Log(address indexed sender, string message);
    event AnotherLog();
    function test() public {
        emit Log(msg.sender, "Hello World!");
        emit Log(msg.sender, "Hello EVM!");
        emit AnotherLog();
    }
}

继承


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract A {
    function foo() public pure virtual returns (string memory) {
        return "A";
    }
    function bar() public pure virtual returns (string memory) {
        return "A";
    }
    function barz() public pure virtual returns (string memory) {
        return "A";
    }
}
// Contracts inherit other contracts by using the keyword 'is'.
contract B is A {
    // Override A.foo()
    function foo() public pure virtual override returns (string memory) {
        return "B";
    }
    function bar() public pure virtual override returns (string memory) {
        return "B";
    }
}
contract C is B {
    // Override A.foo()
    function bar() public pure virtual override returns (string memory) {
        return "C";
    }
}

多线继承


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
    //  X
    // / \
    // Y  \
    // \  /
    //   Z
 
contract X {
    function foo() public pure virtual returns (string memory) {
        return "X";
    }
    function bar() public pure virtual returns (string memory) {
        return "X";
    }
    function _X() public pure  returns (string memory) {
        return "X";
    }
}
// Contracts inherit other contracts by using the keyword 'is'.
contract Y is X {
    // Override A.foo()
    function foo() public pure virtual override returns (string memory) {
        return "Y";
    }
    function bar() public pure virtual override returns (string memory) {
        return "Y";
    }
    function _Y() public pure  returns (string memory) {
        return "Y";
    }
}

//按基类和派生顺序继承

contract Z is X,Y {
    // Override A.foo()
    function bar() public pure virtual override(X,Y) returns (string memory) {
        return "Z";
    }
    function foo() public pure virtual override(X,Y) returns (string memory) {
        return "Z";
    }
    function _Z() public pure  returns (string memory) {
        return "Z";
    }
}

运行父级合约构造函数


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract S {
   
    string public text;
    constructor(string memory _text){
        text = _text;
    }
 
}
contract T {
   
    string public name;
    constructor(string memory _name){
        name = _name;
    }
 
}
//已知构造函数
contract V is S("s"),T("t") {
   
 
}
//未知构造函数
contract VV is S,T {
   
    constructor(string memory _text,string memory _name) S(_text) T(_name){
       
    }
 
}
//混合使用
contract VVV is S("s"),T {
   
    constructor(string memory _name) T(_name){
       
    }
 
}

调用父级合约函数


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
/* Inheritance tree
   A
 /  \
B   C
 \ /
  D
*/
contract A {
    event Log(string message);
    function foo() public virtual {
        emit Log("A.foo called");
    }
    function bar() public virtual {
        emit Log("A.bar called");
    }
}
contract B is A {
    function foo() public virtual override {
        emit Log("B.foo called");
        //第一种调用方式
        A.foo();
    }
    function bar() public virtual override {
        emit Log("B.bar called");
        //第二种调用方式
        super.bar();
    }
}
contract C is A {
    function foo() public virtual override {
        emit Log("C.foo called");
        A.foo();
    }
    function bar() public virtual override {
        emit Log("C.bar called");
        super.bar();
    }
}
//当 B , C 到基类长度相等时,只调用最后面的B
contract D is  C,B {
    // Try:
    // - Call D.foo and check the transaction logs.
    //   Although D inherits A, B and C, it only called C and then A.
    // - Call D.bar and check the transaction logs
    //   D called C, then B, and finally A.
    //   Although super was called twice (by B and C) it only called A once.
    function foo() public override(B, C) {
        super.foo();
    }
    function bar() public override(B, C) {
        super.bar();
    }
}

可视范围


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract VisibilityBase{
    uint private x;
    uint internal y;
    uint public z;
    function privateFunc() private pure returns(uint){
    }
    function internalFunc() internal pure returns(uint){
    }
    function publicFunc() public pure returns(uint){
    }
    function externalFunc() external pure returns(uint){
    }
    function examples() public view returns(uint res){
        res = x + y + z;
        privateFunc();
        internalFunc();
        publicFunc();
        //先到外部再call
        this.externalFunc();
    }
}

不可变量


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Immutable {
    // 节省gas:但是必须在部署合约时赋值
    address public immutable MY_ADDRESS;
    uint public immutable MY_UINT;
    constructor(uint _myUint) {
        MY_ADDRESS = msg.sender;
        MY_UINT = _myUint;
    }
}

支付ETH


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Payable {
    /*地址有两种类型
    address
    payable address 多了两个成员方法send和transfer
    send方法相比较transfer方法来说更“底层”一些,如果send方法执行失败,并不会抛出异常,而是返回false。
    */
    address payable public owner;
    // 普通address需要强转payable address
    constructor() payable {
        owner = payable(msg.sender);
    }
    function deposit() public payable {}
    function getBalance() public view returns(uint){
        return address(this).balance;
    }
}

回退函数


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Fallback {
    event Log(string message,uint gas);
    /*      fallback() or receive() ?
                    ETH Send
                       |
                msg.data is empty?
                    /       \
                   /         \
                yes           no
                |              |
        receive() exists?    fallback()
             /    \
            /      \
           yes      no
           |         |
        receive()  fallback()
    */
    fallback() external payable {
     
        emit Log("fallback()",gasleft());
    }
    receive() external payable {
        emit Log("receive()",gasleft());
    }
    // Helper function to check the balance of this contract
    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}
contract SendToFallback {
    function transferToFallback(address payable _to) public payable {
        _to.transfer(msg.value);
    }
    function callFallback(address payable _to) public payable {
        (bool sent, ) = _to.call{value: msg.value}("123");
        require(sent, "Failed to send Ether");
    }
}

发送ETH

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract ReceiveEther {
    event Log(uint amount,uint gas);
    receive() external payable {
        emit Log(msg.value,gasleft());
    }
}
contract SendEther {
    event Log(bool sent);
    function sendViaTransfer(address payable _to) public payable {
        // This function is no longer recommended for sending Ether.
        _to.transfer(msg.value);
    }
    function sendViaSend(address payable _to) public payable {
        // Send returns a boolean value indicating success or failure.
        // This function is not recommended for sending Ether.
        bool sent = _to.send(msg.value);
        emit Log(sent);
        require(sent, "Failed to send Ether");
    }
    function sendViaCall(address payable _to) public payable {
        // Call returns a boolean value indicating success or failure.
        // This is the current recommended method to use.
        (bool sent, bytes memory data) = _to.call{value: msg.value,gas:222222}("");
        require(sent, "Failed to send Ether");
    }
}

钱包合约


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract EtherWallet {
    address payable public owner;
    constructor() {
        owner = payable(msg.sender);
    }
    receive() external payable {}
    function withdraw(uint _amount) external {
        require(msg.sender == owner, "caller is not owner");
        payable(msg.sender).transfer(_amount);
    }
    function getBalance() external view returns (uint) {
        return address(this).balance;
    }
}
 
 

最新文章

  1. C#6.0 十大常用特性
  2. JavaScript下的setTimeout(fn,0)意味着什么?
  3. 【DP】HIHO 1078
  4. HTML的基本代码第一课
  5. nested exception is java.lang.RuntimeException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: Result Maps collection already contains value for
  6. php报错日志:PHP Deprecated:Automatically populating $HTTP_RAW_POST_DATA is deprecated
  7. CUDA学习笔记(三)——CUDA内存
  8. BZOJ_1614_ [Usaco2007_Jan]_Telephone_Lines_架设电话线_(二分+最短路_Dijkstra/Spfa)
  9. Linux各种包安装及命令
  10. 正则表达式之match与exec【转的 楼兰之风】
  11. 老旧Webkit浏览器行内元素0间距问题
  12. C--运算符,表达式和语句实例
  13. extjs中,datefield日期,点击输入框弹出日期,禁止手动输入
  14. Java原子类中CAS的底层实现
  15. Linux系统下配置网络、JAVA环境,配置tomcat,mysql
  16. LeetCode算法题-Second Minimum Node In a Binary Tree(Java实现)
  17. sizeof和strlen()区别及用法
  18. 微信中H5网页如何唤醒打开外部浏览器打开指定链接
  19. 在Spring(4.3.22)中集成Hibernate(5.4.0)
  20. cp命令覆盖文件时不用按Y来确认的方法

热门文章

  1. Linux下“减速”查看日志的方法
  2. 【转载】EXCEL VBA 自定义排序的三种方法
  3. 深入理解 Linux 物理内存分配全链路实现
  4. JavaScript 中如何拦截全局 Fetch API 的请求和响应?
  5. UnoCSS 简化 CSS 的书写,Nice!
  6. Blazor WebAssembly的初次访问慢的优化
  7. 【Vue3.0】关于 script setup 语法糖的用法
  8. 第 1 天|基于 AI 进行游戏开发:5 天创建一个农场游戏!
  9. ChatGPT保姆级注册教程
  10. C#DataTable(转List /JSON/字典 互转)