真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

智能合約編程語言-solidity快速入門(上)-創(chuàng)新互聯(lián)

solidity簡介

本文默認讀者已掌握至少一種面向?qū)ο缶幊陶Z言,所以文中一些概念會借助其他語言進行類比。

在滕州等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè) 網(wǎng)站設(shè)計制作定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),網(wǎng)絡(luò)營銷推廣,成都外貿(mào)網(wǎng)站制作,滕州網(wǎng)站建設(shè)費用合理。

solidity是用于實現(xiàn)智能合約的一種面向合約的高級編程語言,solidity受到C++、Python和JavaScript的影響,被設(shè)計為可運行在以太坊虛擬機(EVM)上,所以用戶無需擔(dān)心代碼的可移植性和跨平臺等問題。solidity是一種靜態(tài)類型的語言,支持繼承、庫引用等特性,并且用戶可自定義復(fù)雜的結(jié)構(gòu)類型。

目前嘗試 Solidity 編程的最好的方式是使用 Remix (由于是網(wǎng)頁IDE可能加載起來需要一定的時間)。Remix 是一個基于 Web 的 IDE,它可以讓你編寫 Solidity 智能合約,然后部署并運行該智能合約,它看起來是這樣子的:
智能合約編程語言-solidity快速入門(上)

也可以使用sublime或vs code等編輯器編寫 Solidity 代碼,然后復(fù)制粘貼到Remix上部署運行。

solidity官網(wǎng)地址如下:

https://solidity.readthedocs.io/en/latest/index.html


合約文件

本小節(jié)我們來說說合約文件,眾所周知任何語言所編寫的代碼都需要存儲在一個文件里,并且該文件都有一個特定的后綴名,我們一般將這種文件稱之為代碼文件。

solidity代碼文件的后綴名為.sol,但我們通常會把使用solidity編寫的文件稱之為合約文件,一個合約文件通常會包含四個部分,其實與我們平時所編寫其他語言的代碼文件是類似的,如下圖所示:
智能合約編程語言-solidity快速入門(上)

版本聲明的代碼需寫在合約文件的開頭,接著可以根據(jù)實際情況導(dǎo)入一些合約,所謂導(dǎo)入合約也就類似于其他面向?qū)ο蟮恼Z言導(dǎo)入某個類的概念。然后就是聲明一個合約,在合約里編寫具體的代碼,其實這里的合約與我們所熟悉的類的概念基本上是一樣的,可以暫時將它們當做同一個東西。

我們先來對一個較為完整的合約代碼進行一個預(yù)覽,在之后會對代碼中的每個部分進行逐一介紹:

// 版本聲明
pragma solidity ^0.4.0;

// 導(dǎo)入一個合約
import "solidity_for_import.sol";

// 定義一個合約
contract ContractTest {
    // 定義一個無符號整型變量
    uint a;

    // 定義一個事件
    event Set_A(uint a);

    // 定義一個函數(shù)
    function setA(uint x) public {
        a = x;
        // 觸發(fā)一個事件
        emit Set_A(x);
    }

    // 定義一個具有返回值的函數(shù)
    function getA() public returns (uint) {
        return a;
    }

    // 自定義一個結(jié)構(gòu)類型
    struct Pos {
        // 定義一個有符號整型變量
        int lat;
        int lng;
    }

    // 定義一個地址類型,每個合約都運行在一個特定的地址上
    address public addr;

    // 定義一個函數(shù)修改器
    modifier owner () {
        require(msg.sender == addr);
        _;
    }

    // 讓函數(shù)使用函數(shù)修改器
    function mine() public owner {
        a += 1;
    }
}

這里對函數(shù)修改器做一個簡單的說明:

函數(shù)修改器的概念類似于python中的裝飾器,其核心目的都是給函數(shù)增加函數(shù)內(nèi)沒有定義的功能,也就是對函數(shù)進行增強

從以上代碼中,可以看到owner 函數(shù)修改器里定義了一句條件代碼,其意義為:

msg.sender等于addr地址變量時,才繼續(xù)往下執(zhí)行,因為這個require函數(shù)是solidity校驗條件用的,若不符合條件就會拋出異常

mine函數(shù)使用了owner函數(shù)修改器后,那么mine函數(shù)在執(zhí)行之前,會先執(zhí)行owner函數(shù)修改器里的條件代碼,也就是說當msg.sender等于addr成立的話,才會執(zhí)行mine函數(shù)里a += 1;的代碼,否則就不會執(zhí)行。從中也可以看出函數(shù)修改器里的_;語句,其實表示的就是mine函數(shù)里的代碼,如此一來在不修改mine函數(shù)的前提下,給mine函數(shù)增加了額外的功能。


solidity 類型

Solidity是一種靜態(tài)類型語言,意味著每個變量(本地或狀態(tài)變量)需要在編譯時指定變量的類型(或至少可以推導(dǎo)出類型),Solidity提供了一些基本類型可以用來組合成復(fù)雜類型。

Solidity和大多數(shù)語言一樣,有兩種類型:

  • 值類型(Value Type) - 變量在賦值或傳參時,總是進行值拷貝。
  • 引用類型(Reference Types)

solidity所包含的值類型如下:
智能合約編程語言-solidity快速入門(上)

注:其中標紅的是最常用的類型

官網(wǎng)關(guān)于solidity類型的文檔地址如下:

https://solidity.readthedocs.io/en/latest/types.html

1.布爾類型取值范圍是true和false,使用bool關(guān)鍵字進行聲明,聲明方式如下:

// 版本聲明
pragma solidity ^0.4.0;

// 定義一個合約
contract ContractTest {
    bool b1 = true;
    bool b2 = false;
}

2.solidity中有兩種整型的定義方式,一種是無符號整型,另一種則是有符號整型。并且支持關(guān)鍵字uint8 到 uint256 (以8步進),uint 和 int 默認對應(yīng)的是 uint256 和 int256。如下示例:

// 版本聲明
pragma solidity ^0.4.0;

// 定義一個合約
contract ContractTest {
    // 定義一個無符號的整型變量
    uint a;
    // 定義一個有符號的整型變量
    int i;
}

solidity常量

在solidity里使用constant關(guān)鍵字來聲明常量,但并非所有的類型都支持常量,當前支持的僅有值類型和字符串:

pragma solidity ^0.4.0;

contract C {
    uint constant x = 32**22 + 8;
    string constant text = "abc";
    bytes32 constant myHash = keccak256("abc");
}

在solidity中還可以將函數(shù)聲明為常量,該函數(shù)的返回值就是常量值,這類函數(shù)將承諾自己不修改區(qū)塊鏈上任何狀態(tài):

// 定義有理數(shù)常量
function testLiterals() public constant returns (int) {
    return 1;
}

// 定義字符串常量
function testStringLiterals() public constant returns (string) {
    return "string";
}

// 定義16進制常量,以關(guān)鍵字hex打頭,后面緊跟用單或雙引號包裹的字符串,內(nèi)容是十六進制字符串
function testHexLiterals() public constant returns (bytes2) {
    return hex"abcd";
}

有理數(shù)常量函數(shù)里的運算可以是任意精度的,不會有溢出的問題:

// 定義有理數(shù)常量
function testLiterals() public constant returns (int) {
    return 1859874861811128585416.0 + 123.0;
}

科學(xué)符號也支持,基數(shù)可以是小數(shù),但指數(shù)必須是整數(shù),如下:

// 定義有理數(shù)常量
function testLiterals() public constant returns (int) {
    return 2e10;
}

solidity地址類型

solidity中使用address關(guān)鍵字聲明地址類型變量,該類型屬于值類型,地址類型主要用于表示一個賬戶地址,一個以太坊地址的長度為20字節(jié)的16進制數(shù),地址類型也有成員,地址是所有合約的基礎(chǔ)。

地址類型的主要成員:

  • 屬性:balance,用來查詢賬戶余額
  • 函數(shù):transfer(),用來轉(zhuǎn)移以太幣(默認以wei為單位)

代碼示例如下:

pragma solidity ^0.4.7;

contract AddrTest {

    // payable關(guān)鍵字定義一個可接受以太幣的函數(shù)
    function deposit() public payable {

    }

    // 查詢賬戶余額
    function getBalance() public constant returns (uint) {
        return this.balance;
    }

    // 轉(zhuǎn)移以太幣
    function transferEther(address towho) public {
        towho.transfer(10);
    }
}

然后我們將這段代碼復(fù)制粘貼到remix中編譯運行看看,首先需要在Compile選項卡中將代碼進行編譯:
智能合約編程語言-solidity快速入門(上)

編譯成功后,到Run選項卡中,部署該合約:
智能合約編程語言-solidity快速入門(上)

部署成功后,可以查看到合約中的各個函數(shù),并且只需要點擊就可以運行指定的函數(shù):
智能合約編程語言-solidity快速入門(上)

此時我們來點擊執(zhí)行一下getBalance函數(shù):
智能合約編程語言-solidity快速入門(上)

可以看到,此時該合約的賬戶余額為0,現(xiàn)在我們來存儲10個wei的以太幣到合約中:
智能合約編程語言-solidity快速入門(上)

此時再執(zhí)行g(shù)etBalance函數(shù),合約余額為10個wei:
智能合約編程語言-solidity快速入門(上)

然后我們再來看看轉(zhuǎn)移/發(fā)送以太幣的transferEther函數(shù),此時我們這個合約地址的余額為10個wei,當我將這10個wei的以太轉(zhuǎn)移到另一個地址后,當前合約的余額為0:
智能合約編程語言-solidity快速入門(上)

在solidity中一個能通過地址合法性檢查(address checksum test)的十六進制常量就會被認為是地址,如:

0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF

而不能通過地址合法性檢查的39到41位長的十六進制常量,會提示一個警告,被視為普通的有理數(shù)常量。

關(guān)于賬戶地址的合法性檢查定義參考如下提案:

https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md


solidity數(shù)組

在上文中我們提到Solidity 類型分為值類型和引用類型,以上小節(jié)介紹了常見的值類型,接下來會介紹一下引用類型。

引用類型是一個復(fù)雜類型,占用的空間通常超過256位, 拷貝時開銷很大,因此我們需要考慮將它們存儲在什么位置,是存儲在memory(內(nèi)存,數(shù)據(jù)不是永久存在)中還是存儲在storage(永久存儲在區(qū)塊鏈)中。

所有的復(fù)雜類型如數(shù)組和結(jié)構(gòu)體都有一個額外的屬性:數(shù)據(jù)的存儲位置(data location),可為memory和storage。根據(jù)上下文的不同,大多數(shù)時候數(shù)據(jù)存儲的位置有默認值,也可以通過指定關(guān)鍵字storage和memory修改它。

函數(shù)參數(shù)(包含返回的參數(shù))默認是memory。而局部復(fù)雜類型變量(local variables)和狀態(tài)變量(state variables) 默認是storage。局部變量即部作用域(越過作用域即不可被訪問,等待被回收)的變量,如函數(shù)內(nèi)的變量,狀態(tài)變量則是合約內(nèi)聲明的公有變量。

除此之外,還有一個存儲位置是:calldata,用來存儲函數(shù)參數(shù),是只讀的,不會永久存儲的一個數(shù)據(jù)位置。外部函數(shù)的參數(shù)(不包括返回參數(shù))被強制指定為calldata。效果與memory差不多。還有一個存儲位置是:calldata,用來存儲函數(shù)參數(shù),是只讀的,不會永久存儲的一個數(shù)據(jù)位置。外部函數(shù)的參數(shù)(不包括返回參數(shù))被強制指定為calldata。效果與memory差不多。

數(shù)組是一種典型的引用類型,在solidity中數(shù)組的定義方式如下:

  • T[k]:元素類型為T,固定長度為k的數(shù)組
  • T[]:元素類型為T,長度可動態(tài)調(diào)整的數(shù)組
  • bytes和string 是一種特殊的數(shù)組,string 可轉(zhuǎn)為 bytes,而bytes則類似于byte[]

數(shù)組類型有兩個主要成員:

  • 屬性:length
  • 函數(shù):push()

具體的示例代碼如下:

pragma solidity ^0.4.7;

contract ArrayTest {
    // 定義一個無符號整型的變長數(shù)組
    uint[] public numbers = [1, 2, 3];

    // 定義一個字符串
    string str = "abcdefg";

    function getNumbersLength() public returns (uint) {
        // 往數(shù)組中添加一個元素
        numbers.push(4);

        // 返回數(shù)組的長度
        return numbers.length;
    }

    function getStrLength() public constant returns (uint) {
        // 將字符串轉(zhuǎn)換為bytes并返回長度
        return bytes(str).length;
    }

    function getFirst() public constant returns (byte) {
        // 將字符串轉(zhuǎn)換為bytes后,通過下標訪問元素
        return bytes(str)[0];
    }

    function newMemory(uint len) public constant returns (uint) {
        // 定義一個定長數(shù)組并通過memory指定數(shù)組的存儲位置
        uint[] memory memoryArr = new uint[] (len);
        return memoryArr.length;
    }

    function changeFirst(uint[3] _data) public constant returns (uint[3]) {
        // 通過索引操作元素
        _data[0] = 0;
        return _data;
    }
}

solidity結(jié)構(gòu)體和映射

Solidity提供struct關(guān)鍵字來定義自定義類型也就是結(jié)構(gòu)體,自定義的類型屬于引用類型,如果學(xué)習(xí)過go語言的話應(yīng)該對其不會陌生。如下示例:

// 版本聲明
pragma solidity ^0.4.7;

// 定義一個合約
contract ContractTest {
    // 聲明一個結(jié)構(gòu)體
    struct Funder {
        address addr;
        uint amount;
    }

    // 將自定義的結(jié)構(gòu)體聲明為狀態(tài)變量
    Funder funder;

    // 使用結(jié)構(gòu)體
    function newFunder() public {
        funder = Funder({addr: msg.sender, amount: 10});
    }
}

solidity擁有映射類型,映射類型是一種鍵值對的映射關(guān)系存儲結(jié)構(gòu),有點類似于python語言中的字典。定義方式為mapping(_KeyType => _KeyValue)。鍵類型允許除映射、變長數(shù)組、合約、枚舉、結(jié)構(gòu)體外的幾乎所有類型值類型沒有任何限制,可以為任何類型包括映射類型。

映射可以被視作為一個哈希表,所有可能的鍵會被虛擬化的創(chuàng)建,映射到一個類型的默認值(二進制的全零表示)。在映射表中,并不存儲鍵的數(shù)據(jù),僅僅存儲它的keccak256哈希值,這個哈希值在查找值時需要用到。正因為此,映射是沒有長度的,也沒有鍵集合或值集合的概念。

映射類型有一點比較特殊,它僅能用來作為狀態(tài)變量,或在內(nèi)部函數(shù)中作為storage類型的引用。

可以通過將映射標記為public,來讓Solidity創(chuàng)建一個訪問器。通過提供一個鍵值做為參數(shù)來訪問它,將返回對應(yīng)的值。映射的值類型也可以是映射,使用訪問器訪問時,要提供這個映射值所對應(yīng)的鍵,不斷重復(fù)這個過程。

示例代碼如下:

// 版本聲明
pragma solidity ^0.4.7;

// 定義一個合約
contract ContractTest {
    // 定義一個映射類型,key類型為address,value類型為uint
    mapping(address => uint) public balances;

    function updateBalance(uint newBalance) public {
        // msg.sender作為鍵,newBalance作為值,將這對鍵值添加到該映射中
        balances[msg.sender] = newBalance;
    }
}

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


網(wǎng)頁名稱:智能合約編程語言-solidity快速入門(上)-創(chuàng)新互聯(lián)
網(wǎng)站路徑:http://weahome.cn/article/jdjcs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部