​面向开发人员的 Solidity:使用Solidity进行ABI编码和解码

  • 时间:
  • 浏览:178
  • 来源:区块链技术网

智能合约基本上由状态变量和函数组成。有些函数是私有的,只能从合约内部访问,但许多函数是公共的,可以从合约外部访问。也就是说,应用程序(和人)可以向合约发送数据并从合约中检索数据。

要将数据发送到合约,我们需要以合约可以读取的方式发送数据。也就是说,它们需要被编码。如何执行这种编码的规则由以太坊虚拟机(EVM)的实现定义。

在本文中,我们将学习一些关于编码规则的知识,以及如何使用solidity对必须作为函数参数发送的数据进行编码和解码。

使用abi.encode()对函数的参数进行编码

Solidity有一个名为abi的全局变量,它有一个encode方法,因此我们可以使用它对任何函数的参数进行编码。让我们从一个简单的例子开始。假设我们有下面这个函数

function myFunction(address _myAddress, uint _myNumber)...

我们只对函数的参数进行编码,即地址和整数。我们可以使用 remix 来创建一个执行此操作的函数。

部署这个合约,并使用以下地址和无符号整数的值调用函数encode(…):(0x5b38da6a701c568545dcfcb03fcb875f56bedddc4, 127),我们得到了结果

0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4000000000000000000000000000000000000000000000000000000000000007f

对结果的快速分析显示,它有64个字节。这是因为编码是以32字节的倍数进行的:

0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4 000000000000000000000000000000000000000000000000000000000000007f

前32个字节包含地址(20个字节),其余32个字节包含整数7f。编码总是十六进制,十六进制的7f是127。

使用abi.decode()解码函数的参数

现在让我们使用Solidity来解码函数的参数。注意,没有必要识别我们正在处理的函数,因为它的签名将在编码参数之前。为了使问题更加复杂,让我们使用动态变量作为参数。

让我们使用以下合约来解码一组值:string、uint和string。

contract Encode {function encode(string memory _string1, uint _uint, string memory _string2) public pure returns (bytes memory) {
        return (abi.encode(_string1, _uint, _string2));
    }function decode(bytes memory data) public pure returns (string memory _str1, uint _number, string memory _str2) {
        (_str1, _number, _str2) = abi.decode(data, (string, uint, string));
    }}

部署,然后使用以下参数(João,3,Paulo)调用函数encode(…),我们有以下返回:

0x0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000054a6fc3a36f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055061756c6f000000000000000000000000000000000000000000000000000000

我们可能期望返回96个字节(3 x 32),因为我们有3个变量。但是,这3个变量中有2个是动态的,对动态变量的编码就没那么简单了。让我把上面的值分解成32字节的数据块。

0000000000000000000000000000000000000000000000000000000000000060 0000000000000000000000000000000000000000000000000000000000000003 00000000000000000000000000000000000000000000000000000000000000a0 0000000000000000000000000000000000000000000000000000000000000005 4a6fc3a36f000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000005 5061756c6f000000000000000000000000000000000000000000000000000000

我将快速解释一下字符串的编码是如何完成的。第一行指向第一个变量,第二行指向第二个变量,第三行指向第三个变量。因为第二个变量的类型是value,所以我们可以直接在第二行检索它的值3。

对于变量类型字符串,第一行包含的数据是关于第一个字符串的信息。在本例中,十六进制数据为60,十进制数据为96。但这意味着什么呢?这意味着第一个字符串的信息是在从数据开始的96个字节之后找到的。

在92字节之后,32字节的块有一个数字:5。这是字符串所占用的字节数,从下一行开始,以utf-8编码:4a6fc3a36f。从十六进制转换为 UTF-8,我们检索到单词“João”。

按照相同的模式,可以检索a0字节之后的第三个字符串,也就是从数据开始的160字节之后的字符串。它说它也有5个字节,它的值是5061756c6f, 是 'Paulo' 的 UTF-8 编码。

现在,我们已经看到了如何手动完成此操作,现在看看如何通过solidity来完成此操作。使用我们在合约中写的函数decode(bytes memory data),可以检索编码后的信息:

还可以使用其他库对变量进行编码和解码,比如web3.eth.abi。目前也有一个在线网站可以用于此,abi.hashex.org/。

Source:https://medium.com/coinmonks/abi-encode-and-decode-using-solidity-2d372a03e110

关于

ChinaDeFi - ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。

本文首发于:https://mp.weixin.qq.com/s/LrjF24bhF0m53lD9q5k5jQ

猜你喜欢

如何成为资深 solidity 智能合约工程师

如何成为资深solidity智能合约工程师#如何成为资深solidity智能合约工程师##Solidity+Hardhat+Ethers熟悉[Solidity](https:/

2022-11-06

Solidity自学笔记

Solidity自学笔记我在GitHub上写了一个Solidity自学笔记,会持续更新希望大家感兴趣的可以关注一下,感兴趣的给个star,就再好不过了前期由于javascrip

2022-11-06

在BSN武汉链上部署solidity智能合约

BSN简介区块链服务网络(Blockchain-basedServiceNetwork)是一个跨云服务、跨门户、跨底层框架,用于部署和运行各类区块链应用的基础设施网络,2020

2022-11-06

Solidity 字节码和操作码基础知识

在本文中,简单地解释一些EVM基础知识。随着我们深入编写智能合约,我们会遇到诸如“PUSH1”、“SSTORE”、“CALLVALUE”等术语。它们是什么,我们甚至应该关心它们

2022-11-06

使用Solidity和IPFS存储DApp

使用Solidity和IPFS存储DApp*想象一下有一个去中心化的存储应用,我们可以彼此分享我们的磁盘,中间没有任何服务器。想象一下,在这个去中心化的应用中,每个文件都可以通

2022-11-06