以太坊的ABI编码

以太坊的ABI编码,第1张

ABI全称Application Binary Interface, 是调用智能合约函数以及合约之间函数调用的消息编码格式定义,也可以理解为智能合约函数调用的接口说明 类似Webservice里的SOAP协议一样;也就是定义 *** 作函数签名,参数编码,返回结果编码等。

使用ABI协议时必须要求在编译时知道类型,即强类型相关

当一个智能合约编译出来后, 他的abi接口定义就确定了 比如下面的智能合约:

生成的字节码:

生成的abi定义:

可以看出, 生成abi包含了2个定义: 函数 lotus , 事件 Log_lotus , 各个字段含义见上 根据该abi定义,就可以生成调用该智能合约函数的abi格式的数据了

格式简单的可以表示为: 函数选择器+参数编码

一个函数调用的前四个字节数据指定了要调用的函数签名。计算方式是使用函数签名的 keccak256 的哈希,取4个字节。

函数名如果有多个参数使用,隔开,要去掉表达式中的所有空格。在geth客户端,通过命令可以得到hash:

由于前面的函数签名使用了四个字节,参数的数据将从第五个字节开始。

根据参数类型,编码规则有所区别:

除了bytes,和string, 其他类型的数据不足32字节长度的需要加0补足32字节 动态长度的编码在例子中介绍

函数: function baz(uint32 x, bool y) :

调用: baz(69, true)

生成的数据如下:

返回结果是一个bool值,在这里,返回的是false:

函数: f(uint,uint32[],bytes10,bytes)

调用: (0x123, [0x456, 0x789], "1234567890", "Hello, world!")

函数选择器: bytes4(sha3("f(uint256,uint32[],bytes10,bytes)"))

对于 固定大小的类型 值 uint256 和 bytes10 ,直接编码值。

对于 动态内容类型 值 uint32[] 和 bytes ,我们先 编码偏移值 ,偏移值是整个值编码的开始到真正存这个数据的偏移值(这里不计算头四个用于表示函数签名的字节)。

所以参数编码数据依次为:

尾部部分的第一个动态参数, [0x456, 0x789] 编码拆解如下:

最后我们来看看第二个动态参数的的编码, Hello, world! 。

所以最终结果是:

比如我在PC上用不管什么样的COMPILER, 只要产生符合LINUX的ELF文件, 用相应的INSTRUCTION SET(比如INTEL, PPC, SPARC) 就可以在一个LINUX机器上运行 调用系统或别人的LIBABI定义了BINARY的文件格式, 内容, 以及装载/卸载程序的要求, 函数调用的参数传递规则, 寄存器, 堆栈的使用等 abi(应用二进制接口)我的理解就是机器代码一层的接口。先说一下api(特指系统调用),api基本上是和机器硬件平台无关但是和 *** 作系统密切相关的接口,一个api调用定义了一个对内核的 *** 作,以及 *** 作的参数。C语言会议函数的形式调用api。
abi,是比api更贴近硬件的一层接口,它规定的是二进制代码之间的调用规则。举个例子来说吧!一个应用程序,调用了so库中的函数或者系统调用,如果它的编译器可以找到被调用函数或者系统调用的话,则编译可以同过,也就是说,它是用的api是正确的。但是,这个调用离成功还很远。。。。。 首先,如果编译出来的代码和运行库函数和系统调用的代码不是一个硬件平台的,则这个应用根本就不能和被调用代码运行在一起,则调用不会成功。
即使库函数、系统调用和是运行在同一硬件平台上的调用也不一定会趁成功。因为程序最终是被编译成二进制代码的,并且是要加载到内存中运行的。那么,在调用
库函数或者系统调用的时候,应用要先要以库函数或者系统调用指定的方式和位置(内存或者寄存器)设置参数,然后通过中断或者其他方式跳转到被调用代码的起
始处进行执行,被调用代码从指定位置去到参数,处理完毕之后再将结果放到指定的位置,最后应用再到指定的地方取回结果,调用完毕!
我认为这个过程中,存放参数和结果的位置属于abi规定的范围,被调用程序的跳转地址或者中断号码也是abi规定的范围。如果存取参数、结果的位置没有明
确的规范,或者调用、被调用双方没有遵照统一个规范,那么这个调用能够根本就不可能成功;如果系统提供的库函数路径不正确,调用也不会成功;如果中断代码
使用错误,调用也不会正确。

ABI是系统与应用之间的协议 一个BINARY(EXEC, LIB)必需符合ABI才能在相应的系统上运行
比如我在PC上用不管什么样的COMPILER, 只要产生符合LINUX的ELF文件, 用相应的INSTRUCTION SET(比如INTEL, PPC, SPARC) 就可以在一个LINUX机器上运行 调用系统或别人的LIB
ABI定义了BINARY的文件格式, 内容, 以及装载/卸载程序的要求, 函数调用时参数传递规则, 寄存器, 堆栈的使用等

这些参数取决于碟机本身,各种碟机都有区别,你可以先找一个别人能放的格式,在kmplayer中打开,右键 看看媒体信息就可以知道具体的参数了,主要看的就是视频格式、尺寸、码率、音频格式和码率。然后按这个参数用格式工厂之类软件转换就可以了。

你运行前都指定文件夹保存的吧。文件应该还在原来指定的文件夹里面吧。运行结束,文件也就自动保存了。这时候修改设置不会改变数据,但是有可能导致文件出错。你按照保存的路径到文件夹找找,找到后再试试,看能不能打开。
另外,建议你用metlab来试试,看看能不能打开。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13405620.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-30
下一篇 2023-07-30

发表评论

登录后才能评论

评论列表(0条)

保存