Merkle树Solidity合约部署报错:参数编码数据长度不正确
Solidity Merkle树合约部署ABI编码错误解决方法
我实现了一个基础Merkle树的Solidity合约,代码如下:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract buildTree{ bytes32[] private leaves; bytes32 private root; constructor(bytes32[] memory _leaves){ uint n = _leaves.length; require(n>0 , "we cannot build a tree"); require(n%2 ==0 , "number of leaves must be even"); leaves = _leaves; root = buildRoot(_leaves); } function buildRoot(bytes32[] memory _elements) private pure returns (bytes32) { uint n = _elements.length; if(n==1){ return _elements[0]; } bytes32[] memory parents=new bytes32[](n/2); for(uint i=0;i<n/2;i++){ bytes32 left = _elements[i*2]; bytes32 right = _elements[i*2 +1]; bytes32 parent = sha256(abi.encodePacked(left,right)); parents[i] = parent; } return buildRoot(parents); } function getRoot() public view returns(bytes32){ return root; } }
部署时传入参数 ["0xabcdef", "0x123456", "0x789abc", "0xdef123"],触发错误:
creation of buildTree errored: Error encoding arguments: Error: incorrect data length (argument=null, value="0xabcdef", code=INVALID_ARGUMENT, version=abi/5.5.0)
错误原因
错误核心是传入的参数不符合bytes32类型的长度要求:bytes32是固定32字节的数据类型,对应十六进制字符串需要是0x前缀加64个十六进制字符(每个字符代表4位,64*4=256位=32字节)。你传入的0xabcdef只有6个十六进制字符,长度远不足32字节,ABI编码器无法将其转换为bytes32类型,因此抛出编码错误。
解决方案
有两种可行的处理方式,根据实际需求选择:
补全短十六进制字符串到标准长度
如果这些短十六进制值就是你要作为叶子节点的原始数据,需要在末尾补0,凑够64个十六进制字符。比如:0xabcdef→0xabcdef00000000000000000000000000000000000000000000000000000000000x123456→0x1234560000000000000000000000000000000000000000000000000000000000
调整后的参数数组可以正常被ABI编码。
使用字符串的哈希值作为叶子节点(更符合Merkle树常规用法)
通常Merkle树的叶子节点是原始数据的哈希值。如果你原本是想传入字符串(比如"abcdef")作为原始数据,应该先对每个字符串做sha256哈希得到bytes32值,再传入合约。
比如:- 对字符串"abcdef"计算哈希:
sha256(abi.encodePacked("abcdef")),得到的结果是0x882f00617b8879f3e45f86a64c9f51f6767f79f341c86c00e035f9678d602d91 - 用这些哈希值组成参数数组,就能正常部署合约。
- 对字符串"abcdef"计算哈希:
内容的提问来源于stack exchange,提问作者krish
相关产品推荐
相关产品推荐

