You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity与Python生成相同字节的SHA256哈希不一致问题及修正

问题原因及修正方案

错误原因

  1. Solidity代码冗余+数据损坏
    你在Solidity中先通过abi.encodePacked把orderId, msg.sender, totalAmount拼接成原始二进制字节,随后转成string再转回bytes。但abi.encodePacked的结果可能包含非UTF-8合法字节,转成string时会出现数据截断或乱码,导致最终的encodedString已经偏离了原始拼接的二进制数据。
  2. Python编码逻辑错误
    你在Python中把encodedString当作UTF-8字符串转成字节,但Solidity中的encodedString是二进制字节序列(可能包含不可见字符、非UTF-8字节),直接用bytes(my_string, 'utf-8')会错误地按UTF-8规则编码,生成完全不同的字节数组,最终哈希结果自然不一致。

修正步骤

第一步:优化Solidity代码(消除冗余+避免数据损坏)

直接去掉转string的冗余步骤,用原始的abi.encodePacked结果计算哈希,同时添加辅助函数把二进制数据转成十六进制字符串输出(方便Python解析):

bytes memory encodedData = abi.encodePacked(orderId, msg.sender, totalAmount);
bytes32 calculatedHash = sha256(encodedData);
// 输出十六进制格式的encodedData,便于Python处理
emit LogData(calculatedHash, bytesToHex(encodedData));

// 辅助函数:将bytes转换为十六进制字符串
function bytesToHex(bytes memory data) public pure returns (string memory) {
    bytes memory hexChars = "0123456789abcdef";
    bytes memory result = new bytes(data.length * 2);
    for (uint256 i = 0; i < data.length; i++) {
        result[i * 2] = hexChars[uint8(data[i]) >> 4];
        result[i * 2 + 1] = hexChars[uint8(data[i]) & 0x0f];
    }
    return string(result);
}

第二步:修正Python代码

根据Solidity的abi.encodePacked规则,分两种场景处理:

场景1:直接用原始参数计算(推荐)

假设orderId和totalAmount是uint256类型,msg_sender是以太坊地址字符串:

import hashlib

def uint256_to_bytes(value):
    # 将uint256转换为32字节大端二进制
    return value.to_bytes(32, byteorder='big')

def address_to_bytes(address_str):
    # 去掉0x前缀,转换为20字节二进制
    return bytes.fromhex(address_str.strip('0x'))

# 替换为实际参数值
order_id = 123
msg_sender = "0xYourWalletAddress"
total_amount = 456

# 按照Solidity abi.encodePacked规则拼接字节
encoded_data = uint256_to_bytes(order_id) + address_to_bytes(msg_sender) + uint256_to_bytes(total_amount)
# 计算SHA256哈希并转为十六进制
hash_result = hashlib.sha256(encoded_data).hexdigest()
print(hash_result)

场景2:从日志获取十六进制encodedData

如果已经拿到Solidity日志输出的十六进制encodedData字符串:

import hashlib

# 替换为日志中的十六进制字符串(去掉0x前缀)
encoded_hex = "abcdef1234567890..."
encoded_data = bytes.fromhex(encoded_hex)
hash_result = hashlib.sha256(encoded_data).hexdigest()
print(hash_result)

内容的提问来源于stack exchange,提问作者Niteesh Chaudhary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 19:37:02