Abiencoderv2

Bixia 1994 2021-08-20 00:37:28 阅读数:1,003

abiencoderv2 abiencoderv

ABIEncoderV2

J'écris des contrats récemment,Les messages d'erreur suivants sont rencontrés lors de la compilation du contrat,Au début, je n'ai jamais pensé à ce qui s'était mal passé,Écris donc cet article pour enregistrement.image20210819222747300.png

Solutions:

Au début du contrat,Ajouter la ligne suivante,PréciserABIMode de codage:

pragma experimental ABIEncoderV2;

Analyse des problèmes:

Ce type d'erreur se réfère à:Les tableaux dynamiques imbriqués sont actuellementSolidityNon pris en charge pour le moment.

Mais dans les contrats existants:Par exemple:BaseBoringBatchable.solDansbatchFonctions:

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));}

Au - dessus de batchEn fonction, Un type est accepté dans son argument de fonction bytes[]Paramètres pour, Si vous mettez simplement cette fonction dans un contrat pour compiler ,Ça va se produire.:

UnimplementedFeatureError: Nested dynamic arrays not implemented here

Alors,Pourquoibytes[] Est un tableau dynamique imbriqué ?

La raison en est quebytes Le type lui - même est un tableau dynamique ,stringC'est aussi,uint[]C'est aussi.image20210819231253988.png

Alors...bytes[] Est un tableau dynamique imbriqué .

bytes[] Disposition en mémoire

Pour ce qui précède batchFonctions,Lebytes[] Besoin de stocker chaque méthode à appeler calldata. Par exemple, nous appellerons la méthode suivante :

function commitEth( address payable _beneficiary, bool readAndAgreedToMarketParticipationAgreement)

Le nôtre. calldataÇa devrait être:

abi.encodePacked(address(this).commitEth.selector, uint256(uint160(address(this))), uint256(0x01));=>0x73973fcb000000000000000000000000c351628eb244ec633d5f21fbd6621e1a683b11810000000000000000000000000000000000000000000000000000000000000001

Est utilisé en mémoire bytes[]Pour:

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; }

Quand trois call_data Placé en mémoire bytes[]Heure, La disposition de la mémoire doit être la suivante: :

0x00 0000000000000000000000000000000000000000000000000000000000000003 // len0x20 0000000000000000000000000000000000000000000000000000000000000080 // loc10x40 00000000000000000000000000000000000000000000000000000000000000e4 // loc20x60 0000000000000000000000000000000000000000000000000000000000000148 // loc30x80 0000000000000000000000000000000000000000000000000000000000000044 // len(part1)0xa0 73973fcb // part10xa4 000000000000000000000000c351628eb244ec633d5f21fbd6621e1a683b1181 // part10xc4 0000000000000000000000000000000000000000000000000000000000000001 // part10xe4 0000000000000000000000000000000000000000000000000000000000000044 // len(part2)0x104 73973fcb // part20x108 000000000000000000000000c351628eb244ec633d5f21fbd6621e1a683b1181 // part20x128 0000000000000000000000000000000000000000000000000000000000000001 // part20x148 0000000000000000000000000000000000000000000000000000000000000044 // len(part3)0x14c 73973fcb // part30x16c 000000000000000000000000c351628eb244ec633d5f21fbd6621e1a683b1181 // part30x18c 0000000000000000000000000000000000000000000000000000000000000001 // part3

image20210820000113755.png

Ce n'est pas tout à fait cohérent. , Il a utilisé data[0]=data[1]=data[2]Conditions, Par conséquent, pointez à plusieurs reprises vers le même point de mémoire .

bytes[] Disposition dans la fente

De même pour ce qui précède batchFonctions,Laissez - le ici.EVM Stockage dans la fente de , Le contrat doit être conçu comme suit: :

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); }}

Encore trois. call_dataÀdataMoyenne,EtdataInEVM La disposition de stockage doit être :

base_key = 0x0000000000000000000000000000000000000000000000000000000000000000base_value = 3part1_key = keccak256(base_key) + 1part1_value = 0x89part2_key = keccak256(base_key) + 2part2_value = 0x89part3_key = keccak256(base_key) + 3part3_value = 0x89sub_part1_key1 = keccak256(part1_key)sub_part1_value1 = 73973fcb000000000000000000000000c351628eb244ec633d5f21fbd6621e1asub_part1_key2 = sub_part1_key1 + 1sub_part1_value2 = 683b118100000000000000000000000000000000000000000000000000000000sub_part1_key3 = sub_part1_key1 + 2sub_part1_value3 = 0000000100000000000000000000000000000000000000000000000000000000

image20210819235635522.png

Demande de recommandation ABIEncoderV2 Matériel connexe ,Merci beaucoup.

Copyright:Cet article est[Bixia 1994]Établi,Veuillez apporter le lien original pour réimprimer,remercier。 https://fra.fheadline.com/2021/08/20210820003707828X.html