-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# ABI编码解码 | ||
|
||
`ABI` (Application Binary Interface,应用二进制接口)是与以太坊智能合约交互的标准.于编码后不包含类型信息,解码时需要注明它们的类型。 | ||
|
||
`ABI编码`有4个函数: | ||
|
||
- abi.encode | ||
- abi.encodePacked | ||
- abi.encodeWithSignature | ||
- abi.encodeWithSelector | ||
|
||
`ABI解码`有1个函数:abi.decode,用于解码`abi.encode`的数据 | ||
|
||
### 编码状态变量: | ||
|
||
``` | ||
uint x = 10; | ||
address addr = 0x7A58c0Be72BE218B41C608b7Fe7C5bB630736C71; | ||
string name = "0xAA"; | ||
uint[2] array = [5, 6]; | ||
``` | ||
|
||
### abi.encode | ||
|
||
`ABI`被设计出来跟智能合约交互,他将每个参数填充为32字节的数据,并拼接在一起。如果你要和合约交互,你要用的就是`abi.encode`。 | ||
|
||
``` | ||
function abiEncode() external view returns (bytes memory result) { | ||
result = abi.encode(x, addr, name, array); | ||
// 编码/解码在线地址: https://adibas03.github.io/online-ethereum-abi-encoder-decoder/#/encode | ||
//000000000000000000000000000000000000000000000000000000000000000a 0 ~ 32 (uint = 10) | ||
//0000000000000000000000007a58c0be72be218b41c608b7fe7c5bb630736c71 32~ 64 (address addr = 0x7A58c0Be72BE218B41C608b7Fe7C5bB630736C71;) | ||
//00000000000000000000000000000000000000000000000000000000000000a0 64~ 96 (偏移量,指向动态数据的起始位置,a0代表string开始位置 16*10 = 160 ,代表存储位置是160 开始) | ||
//0000000000000000000000000000000000000000000000000000000000000005 96~ 128 (uint[2] array[0] = 5) | ||
//0000000000000000000000000000000000000000000000000000000000000006 128~ 160 (uint[2] array[0] = 5) | ||
//0000000000000000000000000000000000000000000000000000000000000004 160~ 192 (代表string的长度) | ||
//3078414100000000000000000000000000000000000000000000000000000000 192~ 224 (代表 0xAA 的十六进制; 线上转换地址 https://string-functions.com/string-hex.aspx) | ||
} | ||
``` | ||
|
||
### abi.encodePacked | ||
|
||
将给定参数根据其所需最低空间编码。它类似 `abi.encode`,但是会把其中填充的很多`0`省略。当你想省空间,并且不与合约交互的时候,可以使用`abi.encodePacked`,例如算一些数据的`hash`时。 | ||
|
||
``` | ||
function abiEncodePacked() external view returns (bytes memory result) { | ||
result = abi.encodePacked(x, addr, name, array); | ||
// 0x000000000000000000000000000000000000000000000000000000000000000a7a58c0be72be218b41c608b7fe7c5bb630736c713078414100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006,由于abi.encodePacked对编码进行了压缩,长度比abi.encode短很多。 | ||
} | ||
``` | ||
|
||
### abi.encodeWithSignature | ||
|
||
与`abi.encode`功能类似,只不过第一个参数为`函数签名`。当调用其他合约的时候可以使用 | ||
|
||
``` | ||
function abiEncodeWithSignature(address _addr, uint256 _x) external returns (uint256) { | ||
(bool success, bytes memory data) = _addr.call( | ||
abi.encodeWithSignature("setX(uint256)", _x) | ||
); | ||
require(success); | ||
uint256 result = abi.decode(data, (uint256)); | ||
return result; | ||
} | ||
``` | ||
|
||
编码结果与`abi.encode`相比前面多了4个字节的函数选择器编码。 | ||
|
||
### abi.encodeWithSelector | ||
|
||
与`abi.encodeWithSignature`功能类似,只不过第一个参数为`函数选择器`,为`函数签名`Keccak哈希的前4个字节 | ||
|
||
``` | ||
function abiEncodeWithSelector(address _addr, uint256 _x) | ||
external | ||
returns (uint256) | ||
{ | ||
// bytes4 selector = bytes4(keccak256("setX(uint256)")); | ||
bytes4 selector = B.setX.selector; | ||
(bool success, bytes memory data) = _addr.call( | ||
abi.encodeWithSelector(selector, _x) | ||
); | ||
require(success); | ||
uint256 result = abi.decode(data, (uint256)); | ||
return result; | ||
} | ||
``` | ||
|
||
与`abi.encodeWithSignature`结果一样。 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.26; | ||
|
||
// hash | ||
contract Helloworld { | ||
string str = "0xAA"; | ||
|
||
function hash(uint _num, string memory _string, address _addr) external pure returns(bytes32){ | ||
return keccak256(abi.encodePacked(_num,_string,_addr)); | ||
} | ||
|
||
function weakHash(string memory _str) external view returns(bool){ | ||
return keccak256(abi.encodePacked(_str)) == keccak256(abi.encodePacked(str)); | ||
} | ||
|
||
function weakHash(string memory _str1,string memory _str2) external pure returns(bool){ | ||
return keccak256(abi.encodePacked(_str1)) == keccak256(abi.encodePacked(_str2)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters