1. 程式人生 > >Solidity基礎入門知識(六)動態大小位元組陣列

Solidity基礎入門知識(六)動態大小位元組陣列

一、動態大小位元組陣列

  • string 是一個動態尺寸的UTF-8編碼字串,它其實是一個特殊的可變位元組陣列,string是引用型別,而非值型別。
  • bytes 動態位元組陣列,引用型別。

根據經驗,在我們不確定位元組資料大小的情況下,我們可以使用string或者bytes,而如果我們清楚的知道或者能夠將位元組數控制在bytes1 ~ bytes32,那麼我們就使用bytes1 ~ bytes32,這樣的話能夠降低儲存成本。

二、常規字串 string 轉換為 bytes

string字串中沒有提供length方法獲取字串長度,也沒有提供方法修改某個索引的位元組碼,不過我們可以將string轉換為bytes

,再呼叫length方法獲取位元組長度,當然可以修改某個索引的位元組碼(等同於:想要獲取一個string的長度,必須轉為bytes;想要修改string的內容,必須轉換為bytes)。

1、原始碼

pragma solidity ^0.4.4;

contract C {

    bytes9 public g = 0x6c697975656368756e;

    string public name = "liyuechun";

    function gByteLength() constant returns (uint) {

        return g.length;
    }

    function
nameBytes() constant returns (bytes) {
return bytes(name); } function nameLength() constant returns (uint) { return bytes(name).length; } function setNameFirstByteForL(bytes1 z) { // 0x4c => "L" bytes(name)[0] = z; } }
  • 2、效果圖

3、說明

function nameBytes
() constant returns (bytes) {
return bytes(name); }

nameBytes這個函式的功能是將字串name轉換為bytes,並且返回的結果為0x6c697975656368756e(即將字串轉換為對應的16進位制數)。0x6c697975656368756e一共為9位元組,也就是一個英文字母對應一個位元組。

function nameLength() constant returns (uint) {

    return bytes(name).length;
}

我們之前講過,string字串它並不提供length方法幫助我們返回字串的長度,所以在nameLength方法中,我們將name轉換為bytes,然後再呼叫length方法來返回位元組數,因為一個位元組對應一個英文字母,所以返回的位元組數量剛好等於字串的長度。

function setNameFirstByteForL(bytes1 z) {

    // 0x4c => "L"
    bytes(name)[0] = z;
}

如果我們想將name字串中的某個字母進行修改,那麼我們直接通過x[k] = z的形式進行修改即可。x是bytes型別的位元組陣列,k是索引,zbyte1型別的變數值。

setNameFirstByteForL方法中,我就將liyuechun中的首字母修改成L,我傳入的z的值為0x4c,即大寫的L

三、漢字字串或特殊字元的字串轉換為bytes

1、特殊字元

pragma solidity ^0.4.4;

contract C {


    string public name = "a!+&520";


    function nameBytes() constant returns (bytes) {

        return bytes(name);
    }

    function nameLength() constant returns (uint) {

        return bytes(name).length;
    }

}

在這個案例中,我們聲明瞭一個name字串,值為a!+&520,根據nameBytesnameLength返回的結果中,我們不難看出,不管是字母數字還是特殊符號,每個字母對應一個byte(位元組)

2、中文字串

pragma solidity ^0.4.4;

contract C {


    string public name = "黎躍春";


    function nameBytes() constant returns (bytes) {

        return bytes(name);
    }

    function nameLength() constant returns (uint) {

        return bytes(name).length;
    }

}
  • solidity 漢字 字串長度

在上面的程式碼中,我們不難看出,黎躍春轉換為bytes以後的內容為0xe9bb8ee8b783e698a5,一共9個位元組。也就是一個漢字需要通過3個位元組來進行儲存。那麼問題來了,以後我們取字串時,字串中最好不要帶漢字,否則計算字串長度時還得特殊處理。

四、建立bytes位元組陣列

pragma solidity ^0.4.4;

contract C {


    bytes public name = new bytes(1);


    function setNameLength(uint length) {

        name.length = length;
    }

    function nameLength() constant returns (uint) {

        return name.length;
    }

}

孔壹學院

五、bytes可變陣列length和push兩個函式的使用案例

pragma solidity ^0.4.4;

contract C {

    // 0x6c697975656368756e
    // 初始化一個兩個位元組空間的位元組陣列
    bytes public name = new bytes(2);

    // 設定位元組陣列的長度
    function setNameLength(uint len) {

        name.length = len;
    }

    // 返回位元組陣列的長度
    function nameLength() constant returns (uint) {

        return name.length;
    }

    // 往位元組陣列中新增位元組
    function pushAByte(byte b) {

        name.push(b);
    }

}

說明:new bytes(2)的意思是新建一個長度為2的可變陣列。當位元組陣列的長度只有2時,如果你通過push往裡面添加了一個位元組,那麼它的長度將變為3,當位元組數組裡面有3個位元組,但是你通過length方法將其長度修改為2時,位元組陣列中最後一個位元組將被從位元組陣列中移除(如果將長度修改為0,那麼陣列將被清空?)。

五、總結

對比分析:

  • 不可變位元組陣列

我們之前的文章中提到過如果我們清楚我們儲存的位元組大小,那麼我們可以通過bytes1,bytes2,bytes3,bytes4,……,bytes32來宣告位元組陣列變數,不過通過bytesI來宣告的位元組陣列為不可變位元組陣列,位元組不可修改,位元組陣列長度不可修改。

  • 可變位元組陣列

我們可以通過bytes name = new bytes(length) - length為位元組陣列長度,來宣告可變大小和可修改位元組內容的可變位元組陣列。

(轉自:孔壹學院,侵刪!)

相關推薦

Solidity基礎入門知識動態大小位元組陣列

一、動態大小位元組陣列string 是一個動態尺寸的UTF-8編碼字串,它其實是一個特殊的可變位元組陣列,string是引用型別,而非值型別。bytes 動態位元組陣列,引用型別。根據經驗,在我們不確定位元組資料大小的情況下,我們可以使用string或者bytes,而如果我們

Solidity基礎入門知識結構體structs

自定義結構體pragma solidity ^0.4.4; contract Students { struct Person { uint age; uint stuID; string name; }

Solidity基礎入門知識列舉、儲存型別和陣列

今天米切爾致敬卡特轉身成功問鼎扣籃王,可惜只有形而無神,就連形都差點意思--!列舉型別:一個變數可能的取值都知道,就可以把它定義為列舉型,然後把變數的值一一列出來,令變數的值只限於列舉出來的值的範圍內。例如月份、星期幾、天氣等情況,列舉型別用enum關鍵字來定義。例子:enu

C語言基礎 入門學習

1.如何大小端轉換 bool IsBig() { int sh = 0x12345678; char*p = (char*)&sh; if (*p == 0x78) { return false; } return true; } int

linux 基礎知識

linux 基礎知識 日誌 日誌的作用:1.解決系統方面的問題2.解決網絡服務的問題3.記錄過往事件 /var/log/ //日誌文件保存位置cron //記錄周期性任務計劃dmesg //開機核心偵測信息lastlog //系統所有行好最近一次的登陸信息mail

Python基礎知識

迴圈,列表,字典 在開始使用 for 迴圈之前,需要在某個位置存放迴圈的結果。最好的方法是使用列表(list),列表就是一個按順序存放東西的容器。首先我們看看如何建立列表: hairs = ['brown', 'blond', 'red'] eyes = ['brown', 'blu

C++基礎知識--類--成員函式的定義--物件的建立與使用--從面向過程到面向物件

一、類   1.類是一種資料型別,將資料與對資料的操作(函式)放到一起。一個類中的資料通常只能通過本類提供的方法進行處理,這些方法成為該類與外部的介面,物件之間通過訊息進行通訊。   2.如果在類的起始點無訪問說明符,系統預設為私有(private)   3.類是一種資料型別,定義時系統不為類分配儲存空

C++基礎知識--類--成員函數的定義--對象的創建與使用--從面向過程到面向對象

物理 邏輯 需要 面向對象技術 函數 span void 成員函數 開發 一、類   1.類是一種數據類型,將數據與對數據的操作(函數)放到一起。一個類中的數據通常只能通過本類提供的方法進行處理,這些方法成為該類與外部的接口,對象之間通過消息進行通訊。   2.如果在類的起

JAVA基礎-其全面詳解Java基礎知識

101、java中會存在記憶體洩漏嗎,請簡單描述。會。如:int i,i2. return (i-i2). //when i為足夠大的正數,i2為足夠大的負數。結果會造成溢位,導致錯誤。102、java中實現多型的機制是什麼?方法的重寫Overriding和過載Overlo

PHP基礎教程動態函式

1.函式和動態函式 函式的命名規範和變數一樣,但是不區分大小寫,以後學到面向物件的方法時,也不區分大小寫。 函式就像一臺機器,比如說其中的一個函式是電飯鍋,如果你沒有加水(函數出錯了),它就會發出響

PHP之新手自學基礎知識——拓展篇之名稱空間

名稱空間概述 什麼是名稱空間?從廣義上來說,名稱空間是一種封裝事物的方法。在很多地方都可以見到這種抽象概念。例如,在作業系統中目錄用來將相關檔案分組,對於目錄中的檔案來說,它就扮演了名稱空間的角色。具體舉個例子,檔案foo.txt 可以同時在目錄/home/g

perl 入門知識1

.com 方法 如果 shift vim lis zed http script <一> 語句及註釋: Perl 語句以分號(;)結尾,用 # 作為一行的註釋,沒有其它語言中那種跨行的註釋。代碼塊用大括號圍起來,這個和 C 類似,但這個大括號在有些地方是強制要

perl入門知識2

連接符 用法 num 路徑 常用函數 表示 取余 運算符 內容 交互式編程你可以在命令行中使用 -e 選項來輸入語句來執行代碼,實例如下:$ perl -e ‘print "Hello World\n"‘輸入以上命令,回車後,輸出結果為:Hello World 腳本式編程

【redis 基礎學習】Redis HyperLogLog

內存 ger detail edi 統計 固定 ogl per ren 摘自:http://www.mayou18.com/detail/o6M0v9mi.html Redis HyperLogLog 結構講解 Redis 在 2.8.9 版本添加了 HyperLog

基礎算法——圖

一個 col 圖結構 gin 深度 關聯 src 最短 gif 一、圖的概念 圖是四類基本邏輯結構集合、線性結構、樹形結構和圖結構裏面的其中一種,即圖結構,圖結構也是其中最為復雜的結構。在圖的結構中,任意兩個結點之間都可能相關,即結點之間的鄰接關系是任意的。而在樹形結構中,

Scala入門系列:面向對象之object

所有 name 應用 eight lac box dfa port clas object Person { private var eyeNum = 2 println("this Person object") def getEyeNum = eyeNum

JavaScript基礎入門教程

構造 圖片 def type 屬於 string 意思 原則 原始類型 js的數據類型   雖然js屬於弱類型語言,但其總共有6種數據類型。弱類型的意思是定義的變量沒有類型的區分,比如先執行 var num=123; 定義了一變量num存儲整數,可接下來執行 num="he

JavaScript基礎入門教程

alert .get OS 全部 isnan rep mut 分別是 只有一個 說明   前一篇博客介紹了js以及一些關於js基本類型的簡單知識,本篇博客將詳細介紹js的基礎類型,捎帶介紹對象類型,更詳細的對象類型的說明將後續再講。 js中類型的說明   js中的類型分

JavaScript基礎入門教程

直接 復制 一般來說 得到 方式 註意 元素 nbsp 通過 說明   前面的兩篇博客介紹了js中的基本知識中的變量類型、標識符等。這篇博客主要談表達式以及運算符。 原始表達式   原始表達式就是表達式中最小的,不能在分割的表達式,一般指變量、常數直接量、關鍵字(tru

Spring動態代理

AR throws 介紹 自己的 根據 spring implement ret new 在上一篇博客中簡單寫了一下靜態代理,這裏主要講一下動態代理 動態代理主要有兩種 JDK動態代理 CGLIB動態代理 那這兩種代理有什麽區別呢? (根據自己的理解總結) 1.JDK動