ABI:合约应用程序二进制接口(ABI:Contract Application Binary Interface)
这是以太坊生态系统中与合约交互的标准方式:
- -从区块链之外
- -用于合约与合约的交互
数据根据其类型进行编码
编码需要架构才能解码
假设
合约的假设前提:
- - 接口函数是强类型的,在编译时已知,是静态的
- - 他们会有他们所调用的合约的接口定义,在编译时就可以获得。
这不适合有以下情况的合约:
- - 动态接口
- - 只有在运行时才知道
函数编码
- 一个函数调用数据的前4个字节指定了要调用的函数。
- 从第5个字节开始:编码的参数args。参数类型由一个逗号来分割
签名:基本原型的规范表达,没有数据位置的指定符
初级类型
- - uint<M>:0<M<=256位的无符号整数类型。
- - int<M>:0 < M <= 256位的二补有符号整数类型。
- - address:等同于uint160,但假定解释和语言类型。它用于计算函数选择器。
- - uint, int: uint256/int256的同义词。
- - bool:限制在0和1值的uint8。
- - fixed<M>x<N>:M位的有符号定点十进制数,8 <= M <= 256,M % 8 == 0,0 < N <= 80。
- - ufixed<M>x<N>: fixed<M>x<N>的无符号变体。
- fixed, ufixed: 固定128x18和ufixed128x18的同义词。
- bytes<M>:M字节的二进制类型,0 < M <= 32。
- function:地址(20字节),后面是一个函数选择器(4字节)。
固定大小ARRAY类型:
- - <type>[M]: 由M个元素组成的固定长度数组,M>=0,给定类型。
非固定大小类型:
- - bytes:动态字节序列。
- - string:动态大小的Unicode字符串,假定为UTF-8编码。
- - <type>[]: 指定类型元素的可变长度数组
图元Tuples
类型可以被组合成一个元组,方法是把它们放在括号里,用逗号隔开。
(T1,T2,...,Tn): T1, ..., Tn类型的元组,n >= 0
有可能来自:
- - 图元的图元。
- - 图元的数组。
- - 零图元(n == 0)。
将Solidity映射到ABI类型
有些Solidity类型不被ABI支持,所以被翻译成:
- - address payable -> address
- - contract -> address
- - enum -> uint8
- - user-defined value types -> underlying value type
- - struct -> tuple
编码设计标准
编码的设计是这样的:
- - 访问一个值所需的读数最多是参数数组结构内该值的深度
- - 变量/数组元素的数据不与其他数据交错,并且是可重定位的。
静态和动态类型
静态类型:在原地进行编码。
动态类型:在当前区块之后的单独位置进行编码。
动态类型。
- - 字节
- - 字符串
- - T[] 用于T
- - T[k]表示动态T,k>=0
- - (T1,...,Tk) 如果Ti是动态的,对于某些1 <= i <= k
所有其他类型都是静态的。