这篇文章主要介绍了ABIEncoderV2 ,文中通过代码以及文档配合进行讲解,很详细,它对在座的每个人的研究和工作具有很经典的参考价值。 如果需要,让我们与区块链资料网一起学习。

https://www.interchains.cc/23902.html

ABIEncoderV2是很好的区块链资料,他说明了区块链当中的经典原理,可以给我们提供资料,ABIEncoderV2学习起来其实是很简单的,

不多的几个较为抽象的概念也很容易理解,之所以很多人感觉ABIEncoderV2比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难

ABIEncoderV2

  • samczsun

求推荐ABIEncoderV2的相关材料,谢谢

ABIEncoderV2

最近在写一些合约,在合约的编译过程中会遇到如下的错误提示,最开始都没有想到是哪里出了问题,故写下这篇文章以作记录。 ABIEncoderV2

解决方案:

在合约头部,添加如下一行,指明ABI编码方式:

pragma experimental ABIEncoderV2;

问题分析:

该种类型的报错是指:嵌套的动态数组在目前的Solidity中暂未被支持。

然而在已有的合约:如BaseBoringBatchable.sol中的batch函数:

function batch(bytes[] calldata calls, bool revertOnFail) external payable returns (bool[] memory successes, bytes[] memory results) {     uint n = calls.length;     successes = new bool[](n);     results = new bytes[](n);     for (uint i = 0; i < n; i++) {         bytes memory data = calls[i];         (bool success, bytes memory result) = address(this).delegatecall(data);         require(success || !revertOnFail, _getRevertMsg(result));         successes[i] = success;         results[i] = result;     } } function _getRevertMsg(bytes memory data) internal returns(string) {     uint len;     uint pointer;     assembly{         len := mload(data)         pointer := add(data, 0x04)     }     if (len < 68) {         return("Transaction reverted silently");     }     return abi.decode(pointer, (string));  }

在上述的batch函数中,其函数参数中接受一个类型为bytes[]的参数,如果简单的把这个函数放入到合约中进行编译,就会产生:

UnimplementedFeatureError: Nested dynamic arrays not implemented here

那么,为什么bytes[]是一个嵌套的动态数组呢?

原因是bytes类型本身就是一个动态数组,string也是,uint[]也是。 ABIEncoderV2

所以bytes[]就是一个嵌套的动态数组。

bytes[]在内存中的排布

针对上述的batch函数,其bytes[]需要存储每一个需要调用的方法的calldata。例如我们要调用如下方法:

function commitEth(     address payable _beneficiary,     bool readAndAgreedToMarketParticipationAgreement )

则我们的calldata应该为:

abi.encodePacked(address(this).commitEth.selector,                   uint256(uint160(address(this))),                   uint256(0x01)); => 0x73973fcb 000000000000000000000000c351628eb244ec633d5f21fbd6621e1a683b1181 0000000000000000000000000000000000000000000000000000000000000001

则在内存中使用bytes[]为:

function hack() public payable{     bytes[] memory data = new bytes[](3);     bytes momory call_data = abi.encodePacked(address(this).commitEth.selector,                                               uint256(uint160(address(this))),                                               uint256(0x01));     data[0] = call_data;     data[1] = call_data;     data[2] = call_data;   }

当把三个call_data放置在内存中的bytes[]时,其内存排布应该如下:

0x00 0000000000000000000000000000000000000000000000000000000000000003 // len 0x20 0000000000000000000000000000000000000000000000000000000000000080 // loc1 0x40 00000000000000000000000000000000000000000000000000000000000000e4 // loc2 0x60 0000000000000000000000000000000000000000000000000000000000000148 // loc3  0x80 0000000000000000000000000000000000000000000000000000000000000044 // len(part1) 0xa0 73973fcb                                                         // part1 0xa4 000000000000000000000000c351628eb244ec633d5f21fbd6621e1a683b1181 // part1 0xc4 0000000000000000000000000000000000000000000000000000000000000001 // part1  0xe4 0000000000000000000000000000000000000000000000000000000000000044 // len(part2) 0x104 73973fcb                                                        // part2 0x108 000000000000000000000000c351628eb244ec633d5f21fbd6621e1a683b1181 // part2 0x128 0000000000000000000000000000000000000000000000000000000000000001 // part2  0x148 0000000000000000000000000000000000000000000000000000000000000044 // len(part3) 0x14c 73973fcb                                                         // part3 0x16c 000000000000000000000000c351628eb244ec633d5f21fbd6621e1a683b1181 // part3 0x18c 0000000000000000000000000000000000000000000000000000000000000001 // part3

ABIEncoderV2

可以发现并不是完全一致,它利用了data[0]=data[1]=data[2]的条件,故重复指向同一个内存位点。

bytes[]在插槽中的排布

同样针对上述batch函数,让其在EVM的插槽中进行存储,则合约应该如下设计:

contract Exploit {     bytes[] public data;     function hack() public payable{         bytes momory call_data = abi.encodePacked(bytes4(0x73973fcb),                                               uint256(uint160(address(this))),                                               uint256(0x01));         data.push(call_data);         data.push(call_data);         data.push(call_data);     } }

同样添加三个call_data到data中,则data在EVM存储时的排布应该为:

base_key = 0x0000000000000000000000000000000000000000000000000000000000000000 base_value = 3 part1_key = keccak256(base_key) + 1 part1_value = 0x89 part2_key = keccak256(base_key) + 2 part2_value = 0x89 part3_key = keccak256(base_key) + 3 part3_value = 0x89 sub_part1_key1 = keccak256(part1_key) sub_part1_value1 = 73973fcb000000000000000000000000c351628eb244ec633d5f21fbd6621e1a sub_part1_key2 = sub_part1_key1 + 1 sub_part1_value2 = 683b118100000000000000000000000000000000000000000000000000000000 sub_part1_key3 = sub_part1_key1 + 2 sub_part1_value3 = 0000000100000000000000000000000000000000000000000000000000000000

ABIEncoderV2

求推荐ABIEncoderV2的相关材料,谢谢

部分转自网络,侵权联系删除www.interchains.cchttps://www.interchains.cc/23902.html

区块链毕设网(www.interchains.cc)全网最靠谱的原创区块链毕设代做网站 部分资料来自网络,侵权联系删除! 最全最大的区块链源码站 ! QQ3039046426
区块链知识分享网, 以太坊dapp资源网, 区块链教程, fabric教程下载, 区块链书籍下载, 区块链资料下载, 区块链视频教程下载, 区块链基础教程, 区块链入门教程, 区块链资源 » ABIEncoderV2

提供最优质的资源集合

立即查看 了解详情