Skip to the content.

Contract Basics

Call Contract

generate contract var

在已知被调用合约的源码(接口)和地址的情况下,可以采取生成合约变量的方式来调用已部署的合约,有以下方式可用用来生成合约变量:

总结: contractName(contractAddr) 来生成合约变量

具体代码实例详见:

call

在不知道合约源码或 ABI 的情况下,可以采用 call 来调用其他合约,具体方式如下:

delegateCall

deleteCall 的调用方式如下:

关系 calldelegateCall 的区别详见: ./24061701-delegate_call.md

summary

调用合约的方式 适应场景 语法
生成合约变量 已知合约源码或 ABI ContractName(contractAddr)
call 不知道合约与源码及 ABI contractAddr.call(abi.encodeWithSignature("函数名(逗号分隔的参数类型)", 逗号分隔的参数))
delegateCall 不知道合约与源码及 ABI contractAddr.delegateCall(abi.encodeWithSignature("函数名(逗号分隔的参数类型)", 逗号分隔的参数))

Contract Create And Destory

create contratc

create

在合约中创建新的合约,语法如下:

    ContractName x = new ContractName{value: _value}(params);

说明:

create2

what is create2

create2 的作用就是能够在合约未部署之前预测合约的地址

why need create2

满足在合约未部署之前,需要事先计算出合约地址的场景

合约地址的计算

创建合约方法 合约地址计算方法 说明
create contractAddr = hash(creatorAddr, nonce)
  • creatorAddr: 部署合约的钱包地址或者是合约地址
  • nonce: 创建者地址的 nonce,由于是可变的,且不能准确预测,所以使用 create 方法创建出来的合约地址,是不可预测的
  • create2 contractAddr = hash("0xFF", creatorAddr, salt, initCode)
  • 0xFF: 常量,用于区分 create 方法
  • creatorAddr: 部署合约的钱包或合约地址
  • salt: 一个创建者指定的 byte32 的值,目的是用来影响创建合约的地址
  • initcode: 新合约的初始字节码(合约的 creation code 和构造函数的参数)
  • how to use create2

    create2 创建合约语法如下:

        ContractName x = new ContractName{salt: _salt, value: _value}(params)
    

    说明:

    destory contract

    ABI Encode And Decode

    what is ABI

    ABI: application binary interface, 应用程序二进制接口,是与合约交互的标准。其数据也是通过了该类型进行编码,由于编码时只包含了数据,在解码时,要申明返回值的类型

    ABI encode

    方法名 备注
    abi.encode(a, b, c)
  • 功能: 将每个参数编码成 32 字节的数据并拼接在一起
  • 使用场景: 当要与合约进行交互时,就要采用该方法来编码参数
  • abi.encodePacked()
  • 功能: 将给定参数按其所需最低空间进行编码,功能类似 abi.encode(),只不过会省略多余填充的 0
  • 使用场景: 不需要与合约交互,想节省一些空间,如计算 hash
  • abi.encideWithSignature()
  • 功能: 与 abi.encode 功能类似,只不过第一个参数为函数签名(functionName(逗号分隔的参数类型))
  • 使用场景: 在合约中调用其他合约时使用
  • abi.encodeWithSelector()
  • 功能: 与 abi.encodeWithSelector 类似,只不过第一个参数为函数选择器(bytes4(keccak256(functionName(逗号分隔的参数类型))))
  • 使用场景: 调用其他合约时使用,其编码结果与 abi.encideWithSignature() 完全一致
  • ABI decode

    abi.decode 用于解码 abi.encode 编码的二进制数据,将它还原成原本的参数,用法如下:

    function decode(bytes memory data) public pure returns(uint dx, address daddr, string memory dname, uint[2] memory darray) {
        (dx, daddr, dname, darray) = abi.decode(data, (uint, address, string, uint[2]));
    }
    

    Hash

    solidity 中常用的哈希函数是 keccak256,其用法如下:

        hash = keccak256(数据)
    

    keccak256 and sha3

    keccak256sha3 的区别和联系:

    Try-Catch

    在 solidity 中 try catch 语法,只能用于外部函数或创建合约时 construct 的调用。基本语法如下

        try externalContract.f() returns(returnType val) {
            // call 成功时执行
        } catch {
            // call 失败时执行
        }
    

    备注: