以太坊开发指南,如何固定字节数组(Bytes)

OKX欧易app

OKX欧易app

欧易交易所app是全球排名第一的虚拟货币交易所,注册领取6万元盲盒礼包!

APP下载   官网注册

以太坊开发指南,如何固定字节数组(Bytes)

以太坊开发指南,如何固定字节数组(Bytes)

在以太坊智能合约开发中,处理数据是核心任务之一,当需要存储一段固定长度的二进制数据时,例如哈希值(如 keccak256 的结果)、公钥、加密密文或任何其他已知长度的原始字节序列,bytes 类型便派上了用场,与可变长度的字节数组 bytes 不同,bytes1 到 bytes32 这种固定大小的字节数组在存储和计算上更具效率,是 Solidity 开发者工具箱中一个非常重要的工具。

本文将详细讲解在以太坊智能合约中如何定义、使用和操作固定字节数组。

什么是固定字节数组?

固定字节数组是一种在声明时就必须指定其长度(从 1 到 32 个字节)的数据类型,一旦声明,其长度在合约的整个生命周期内都不可改变。

这种类型的优势在于:

  • Gas 效率高:因为长度固定,编译器和 EVM(以太坊虚拟机)可以对其进行高度优化,存储和读取操作比可变长度字节数组消耗更少的 Gas。
  • 内存布局紧凑:在内存和存储中,它们被紧密地排列,没有额外的长度存储开销。
  • 类型安全:编译器会强制执行类型规则,例如你不能将一个 bytes32 直接赋值给一个 bytes20 变量,需要显式转换。

如何声明和初始化固定字节数组?

声明固定字节数组非常简单,使用 bytes1 到 bytes32 的关键字,后跟变量名。

语法: bytes1 到 bytes32 变量名;

示例:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract FixedBytesExample {
    // 声明一个 32 字节的字节数组,通常用于存储哈希值
    bytes32 public myHash;
    // 声明一个 20 字节的字节数组,通常用于存储以太坊地址
    bytes20 public myAddress;
    // 声明一个 16 字节的字节数组,例如用于 AES-128 的密钥
    bytes16 public mySecretKey;
    // 声明一个 1 字节的字节数组
    bytes1 public myFlag;
    // 构造函数中进行初始化
    constructor() {
        // 可以通过字面量直接赋值
        // 字面量必须是有效的十六进制字符串,且长度必须匹配
        myHash = 0x608060405234801561001057600080fd5b5061015a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806360fe47b1146100465780636d4ce63c14610064575b600080fd5b61004e61008a565b60405161005b91906100f9565b60405180910390f35b61007e6004803603810190610079919061014d565b610093565b60405161008b91906100f9565b60405180910390f35b60008054905090565b8060008190555050565b6000813590506100b6816101a4565b92915050565b6000602082840312156100d2576100d161019c565b5b60006100e0848285016100a7565b91505092915050565b6100f18161017c565b82525050565b600060208201905061010c60008301846100e8565b92915050565b6000819050919050565b600061012661012161011d565b61017c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b8381101561016a57808201518184015260208101905061014f565b83811115610179576000848401525b50505050565b6000600282049050600182168061019757607f821691505b602082108114156101ab576101aa6101c9565b5b50919050565b6101ba8161017c565b81146101c557600080fd5b5056fea2646970667358221220c1b5b3c4d2e4a8a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a64736f6c63430008070033";
        // 也可以使用十六进制字符串
        myAddress = 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045; // Vitalik Buterin's address
        // 初始化 mySecretKey
        mySecretKey = 0x1234567890abcdef1234567890abcdef;
        // 初始化 myFlag
        myFlag = 0xff; // 设置为全 1,表示 true
    }
}

关键点:

  • 字面量赋值:可以使用 0x 开头的十六进制字面量直接赋值,编译器会检查其长度是否与变量类型匹配。
  • 变量间赋值:长度相同的固定字节数组可以直接相互赋值。
  • 类型转换:长度不同的字节数组不能直接赋值,需要使用类型转换,这通常会导致高位被截断或低位被填充,需谨慎使用。

如何访问和修改固定字节数组?

固定字节数组的元素可以通过索引从 0 开始访问,每个索引对应一个字节(8位)。

语法: 数组名[索引位置];

示例:

contract BytesAccessExample {
    bytes32 public myData = 0x68656c6c6f20776f726c6421deadbeefcafe00000000000000000000000000000000;
    // 获取第 0 个字节 (0x68, 即 'h' 的 ASCII 码)
    function getByte0() public pure returns (bytes1) {
        return myData[0];
    }
    // 获取第 4 个字节 (0x6f, 即 'o' 的 ASCII 码)
    function getByte4() public pure returns (bytes1) {
        return myData[4];
    }
    // 修改第 30 个字节
    function modifyByte30(bytes1 newValue) public {
        myData[30] = newValue;
    }
    // 修改多个字节(通过拼接)
    function modifyFirst5Bytes(bytes5 newValue) public {
        // 将 myData 的前 5 个字节替换为 newValue
        myData = bytes32(bytes32(newValue) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 | bytes32(myData) & 0x000000000000000000000000000000000000000000000000000000000000FFFF);
        // 注意:直接修改多个字节需要位运算,比较繁琐。
        // 更好的方法是先将整个数组读出,修改内存中的副本,然后重新赋值。
    }
}

注意:

  • 修改单个字节是允许的。
  • 修改连续的多个字节没有直接的语法糖,通常需要通过位运算(&, , <<)来完成,这可能会使代码变得复杂,一个更清晰的方法是先将 bytes32 读取到内存中,创建一个副本进行修改,然后将整个值写回存储。

常用方法和操作

固定字节数组拥有一些内置的成员方法,非常实用。

  • .length:返回字节数组的长度

本文来自用户投稿,不代表币大大立场,如若转载,请注明出处:https://czxurui.com/jys/303286.html

上一篇 2026年09月04日
下一篇 2026年09月04日

相关推荐

  • 以太坊真实价格最近,市场波动背后的多重逻辑

    以太坊真实价格最近,市场波动背后的多重逻辑 以太坊(ETH)的价格走势成为加密市场关注的焦点,其“真实价格”的讨论也愈发激烈,不同于单一的市场报价,以太坊的真实价格更多反映的是其作为“全球第二大加密资产”的内在价值与市场情绪的博弈,近期主要呈现震荡上行的特征,

    2026-10-20 12:10:01
    2 0
  • 你会出售你的以太坊吗?当加密世界的信仰遇上现实的柴米油盐

    你会出售你的以太坊吗?当加密世界的信仰遇上现实的柴米油盐 “你会出售你的以太坊吗?”这个问题,像一颗投入加密社区的石子,总能激起层层涟漪,对于手持ETH的投资者、信徒或是好奇的观望者而言,它从来不是一个简单的“是”或“否”能回答的问题,它背后,藏着对价值的判断

    2026-10-20 08:10:02
    3 0
  • 以太坊经典(ETC)发行价回顾,从以太坊分叉之初的价值起点

    以太坊经典(ETC)发行价回顾,从以太坊分叉之初的价值起点 在加密货币领域,以太坊经典(Ethereum Classic,ETC)是一个具有特殊历史意义的项目,它诞生于2016年以太坊社区的“硬分叉”事件,旨在坚守“代码即法律”的区块链原始精神,对于投资者和研究者而言,了解ETC的发行

    2026-10-20 08:10:02
    6 0
  • V神与以太坊的下一站,从合并到去中心化的星辰大海

    V神与以太坊的下一站,从合并到去中心化的星辰大海 在加密世界的璀璨星河中,如果说比特币是那颗最耀眼的“数字黄金”,那么以太坊则无疑是驱动整个智能经济生态的“世界计算机”,而在这台宏伟计算机的背后,站着一位被社区亲切地称为“V神”(Vitalik Buterin)的天才少年,

    2026-10-20 08:10:02
    7 0
  • 小狐狸钱包(MetaMask)以太坊星号功能使用指南,轻松管理Gas费

    小狐狸钱包(MetaMask)以太坊星号功能使用指南,轻松管理Gas费 在去中心化金融(DeFi)和以太坊生态的浪潮中,MetaMask(小狐狸钱包)无疑是用户最常用的以太坊钱包之一,它不仅帮助用户安全地管理加密资产,更是与各种DApp(去中心化应用)交互的桥梁,许多MetaMask用户在转

    2026-10-20 06:10:02
    4 0
  • 以太坊一年涨幅几何?回顾过去一年的涨跌沉浮与未来展望

    以太坊一年涨幅几何?回顾过去一年的涨跌沉浮与未来展望 在波澜壮阔的加密货币市场中,以太坊(Ethereum)无疑是仅次于比特币的“巨无霸”,它不仅仅是一种数字资产,更是一个庞大的去中心化应用平台,是全球无数开发者、投资者和用户关注的焦点,对于许多投资者而言,最关心

    2026-10-20 06:10:02
    7 0

发表回复

8206

评论列表(0条)

    暂无评论

binance币安交易所
已有2000万用户加入币安交易所

立即下载