国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Solidity 簡易教程

chenatu / 1255人閱讀

摘要:語句以分號結(jié)尾狀態(tài)變量狀態(tài)變量是被永久地保存在合約中。中,實(shí)際上是代名詞,一個(gè)位的無符號整數(shù)。下面的語句被認(rèn)為是修改狀態(tài)修改狀態(tài)變量。事件事件是合約和區(qū)塊鏈通訊的一種機(jī)制。一旦它被發(fā)出,監(jiān)聽該事件的都將收到通知。

Solidity是以太坊的主要編程語言,它是一種靜態(tài)類型的 JavaScript-esque 語言,是面向合約的、為實(shí)現(xiàn)智能合約而創(chuàng)建的高級編程語言,設(shè)計(jì)的目的是能在以太坊虛擬機(jī)(EVM)上運(yùn)行。

本文基于CryptoZombies,教程地址為:https://cryptozombies.io/zh/

合約

Solidity 的代碼都包裹在合約里面. 一份合約就是以太應(yīng)幣應(yīng)用的基本模塊, 所有的變量和函數(shù)都屬于一份合約, 它是你所有應(yīng)用的起點(diǎn).

一份名為 HelloWorld 的空合約如下:

contract HelloWorld {

}
hello world

首先看一個(gè)簡單的智能合約。

pragma solidity ^0.4.0;

contract SimpleStorage {
    uint storedData; // 聲明一個(gè)類型為 uint (256位無符號整數(shù))的狀態(tài)變量,叫做 storedData

    function set(uint x) public {
        storedData = x; // 狀態(tài)變量可以直接訪問,不需要使用 this. 或者 self. 這樣的前綴
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

所有的 Solidity 源碼都必須冠以 "version pragma" — 標(biāo)明 Solidity 編譯器的版本. 以避免將來新的編譯器可能破壞你的代碼。

例如: pragma solidity ^0.4.0; (當(dāng)前 Solidity 的最新版本是 0.4.0).

關(guān)鍵字 pragma 的含義是,一般來說,pragmas(編譯指令)是告知編譯器如何處理源代碼的指令的(例如, pragma once )。

Solidity中合約的含義就是一組代碼(它的 函數(shù) )和數(shù)據(jù)(它的 狀態(tài) ),它們位于以太坊區(qū)塊鏈的一個(gè)特定地址上。

該合約能完成的事情并不多:它能允許任何人在合約中存儲(chǔ)一個(gè)多帶帶的數(shù)字,并且這個(gè)數(shù)字可以被世界上任何人訪問,且沒有可行的辦法阻止你發(fā)布這個(gè)數(shù)字。當(dāng)然,任何人都可以再次調(diào)用 set ,傳入不同的值,覆蓋你的數(shù)字,但是這個(gè)數(shù)字仍會(huì)被存儲(chǔ)在區(qū)塊鏈的歷史記錄中。

Solidity 語句以分號(;)結(jié)尾
狀態(tài)變量

狀態(tài)變量是被永久地保存在合約中。也就是說它們被寫入以太幣區(qū)塊鏈中,想象成寫入一個(gè)數(shù)據(jù)庫。

contract HelloWorld {
   // 這個(gè)無符號整數(shù)將會(huì)永久的被保存在區(qū)塊鏈中
   uint myUnsignedInteger = 100;
}

在上面的例子中,定義 myUnsignedIntegeruint 類型,并賦值100。

uint 無符號數(shù)據(jù)類型, 指其值不能是負(fù)數(shù),對于有符號的整數(shù)存在名為 int 的數(shù)據(jù)類型。

Solidity中, uint 實(shí)際上是 uint256代名詞, 一個(gè)256位的無符號整數(shù)。

程序有時(shí)需要對不同類型的數(shù)據(jù)進(jìn)行操作,因?yàn)?Solidity 是靜態(tài)類型語言,對不同類型的數(shù)據(jù)進(jìn)行運(yùn)算會(huì)拋出異常,比如:

uint8 a = 5;
uint b = 6;
// 將會(huì)拋出錯(cuò)誤,因?yàn)?a * b 返回 uint, 而不是 uint8:
uint8 c = a * b;

a * b 返回類型是 uint, 但是當(dāng)我們嘗試用 uint8 類型接收時(shí), 就會(huì)造成潛在的錯(cuò)誤。這時(shí),就需要顯式的進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換:

// 我們需要將 b 轉(zhuǎn)換為 uint8:
uint8 c = a * uint8(b);
把它的數(shù)據(jù)類型轉(zhuǎn)換為 uint8, 就可以了,編譯器也不會(huì)出錯(cuò)。

Solidity 支持多種數(shù)據(jù)類型,比如:

string(字符串):字符串用于保存任意長度的 UTF-8 編碼數(shù)據(jù)

fixedArray(靜態(tài)數(shù)組):固定長度的數(shù)組

dynamicArray(動(dòng)態(tài)數(shù)組):長度不固定,可以動(dòng)態(tài)添加元素的數(shù)組

enum(枚舉)

mapping

數(shù)學(xué)運(yùn)算

在 Solidity 中,數(shù)學(xué)運(yùn)算很直觀明了,與其它程序設(shè)計(jì)語言相同:

加法: x + y

減法: x - y,

乘法: x * y

除法: x / y

取模 / 求余: x % y (例如, 13 % 5 余 3, 因?yàn)?3除以5,余3)

乘方: x ** y

結(jié)構(gòu)體

Solidity 提供了 結(jié)構(gòu)體,用來表示更復(fù)雜的數(shù)據(jù)類型。

struct Person {
  uint age;
  string name;
}

結(jié)構(gòu)體允許你生成一個(gè)更復(fù)雜的數(shù)據(jù)類型,它有多個(gè)屬性。

創(chuàng)建結(jié)構(gòu)體方式為:

// 創(chuàng)建一個(gè)新的Person:
Person satoshi = Person(172, "Satoshi");
數(shù)組

Solidity 提供兩種類型的數(shù)組:靜態(tài)數(shù)組動(dòng)態(tài)數(shù)組。

// 固定長度為2的靜態(tài)數(shù)組:
uint[2] fixedArray;
// 固定長度為5的string類型的靜態(tài)數(shù)組:
string[5] stringArray;
// 動(dòng)態(tài)數(shù)組,長度不固定,可以動(dòng)態(tài)添加元素:
uint[] dynamicArray;

使用 push 函數(shù)向數(shù)組中添加值:

fixedArray.push[123] 
fixedArray.push[234]
// fixedArray 值為 [123, 234]
array.push() 在數(shù)組的 尾部 加入新元素 ,所以元素在數(shù)組中的順序就是添加的順序
array.push() 會(huì)返回?cái)?shù)組的長度。

Solidity 數(shù)組支持多種類型,比如結(jié)構(gòu)體:

struct Person {
  uint age;
  string name;
}

Person[] people; // dynamic Array, we can keep adding to it

結(jié)構(gòu)體類型的數(shù)組添加值的方式為:

people.push(Person(16, "Vitalik"));
// 也可以使用下面的方式,推薦使用上述一行簡潔的方式

Person satoshi = Person(172, "Satoshi");
people.push(satoshi);
公共數(shù)組

也可以使用public定義公共數(shù)組,Solidity 會(huì)自動(dòng)創(chuàng)建getter方法。語法如下:

struct Person {
  uint age;
  string name;
}

Person[] public people; // dynamic Array, we can keep adding to it
公共數(shù)組支持其它的合約讀取數(shù)據(jù)(但不能寫入數(shù)據(jù)),所以這在合約中是一個(gè)有用的保存公共數(shù)據(jù)的模式。(有點(diǎn)像全局變量,所有合約共享同一個(gè)“內(nèi)存空間“,厲害了!)
函數(shù)

Solidity 中,函數(shù)定義如下:

function eatHamburgers(string _name, uint _amount) {

}
Solidity  習(xí)慣上函數(shù)里的變量都是以(_)開頭 (但不是硬性規(guī)定) 以區(qū)別全局變量。

這是一個(gè)名為 eatHamburgers 的函數(shù),它接受兩個(gè)參數(shù):一個(gè) string類型的 和 一個(gè) uint類型的?,F(xiàn)在函數(shù)內(nèi)部還是空的。

函數(shù)調(diào)用如下:

eatHamburgers("vitalik", 100);
私有/公共函數(shù)

Solidity 函數(shù)分為私有函數(shù)和共有函數(shù)。

Solidity 定義的函數(shù)的屬性默認(rèn)為公共。 這就意味著任何一方 (或其它合約) 都可以調(diào)用你合約里的函數(shù)。

顯然,不是什么時(shí)候都需要這樣,而且這樣的合約易于受到攻擊。所以將自己的函數(shù)定義為私有是一個(gè)好的編程習(xí)慣,只有當(dāng)你需要外部世界調(diào)用它時(shí)才將它設(shè)置為公共

可以把所有的函數(shù)都顯式的聲明 publicprivate來規(guī)避這個(gè)問題。

定義私有函數(shù)比較簡單,只需要在函數(shù)參數(shù)后添加 private關(guān)鍵字即可。示例如下:

uint[] numbers;

function _addToArray(uint _number) private {
  numbers.push(_number);
}

這意味著只有我們合約中的其它函數(shù)才能夠調(diào)用這個(gè)函數(shù),給 numbers數(shù)組添加新成員。

和函數(shù)的參數(shù)類似,私有函數(shù)的名字用(_)起始。
注意:在智能合約中你所用的一切都是公開可見的,即便是局部變量和被標(biāo)記成 private 的狀態(tài)變量也是如此。
返回值

和其它語言一樣,Solidity 函數(shù)也有返回值,示例如下:

string greeting = "What"s up dog";

function sayHello() public returns (string) {
  return greeting;
}

返回值使用 returns關(guān)鍵字標(biāo)注。(已經(jīng)是非常奇怪的寫法了。。)

修飾符
view
constantview 的別名
string greeting = "What"s up dog";

function sayHello() public returns (string) {
  return greeting;
}

sayHello 函數(shù)這種實(shí)際上沒有改變合約中數(shù)據(jù)內(nèi)容的情況,可以把函數(shù)定義為view,這意味著此函數(shù)只讀不修改數(shù)據(jù)??梢允褂靡韵侣暶鞣绞剑?/p>

function sayHello() public view returns (string) {}

可以將函數(shù)聲明為 view 類型,這種情況下要保證不修改狀態(tài)。

下面的語句被認(rèn)為是修改狀態(tài):

修改狀態(tài)變量。

產(chǎn)生事件。

創(chuàng)建其它合約。

使用 selfdestruct

通過調(diào)用發(fā)送以太幣。

調(diào)用任何沒有標(biāo)記為 view 或者 pure 的函數(shù)。

使用低級調(diào)用。

使用包含特定操作碼的內(nèi)聯(lián)匯編。

pure

pure 比 view 更輕量,使用這個(gè)修飾符修飾的函數(shù)甚至都不會(huì)讀取合約中的數(shù)據(jù),例如:

function _multiply(uint a, uint b) private pure returns (uint) { return a * b; }

這個(gè)函數(shù)沒有讀取應(yīng)用里的狀態(tài),它的返回值只和它輸入的參數(shù)相關(guān)。

Solidity 編輯器會(huì)給出提示,提醒你使用 pure/view修飾符。

函數(shù)可以聲明為 pure ,在這種情況下,承諾不讀取或修改狀態(tài)。

除了上面解釋的狀態(tài)修改語句列表之外,以下被認(rèn)為是從狀態(tài)中讀?。?/p>

讀取狀態(tài)變量。

訪問 this.balance 或者

.balance。

訪問 block,tx, msg 中任意成員 (除 msg.sigmsg.data 之外)。

調(diào)用任何未標(biāo)記為 pure 的函數(shù)。

使用包含某些操作碼的內(nèi)聯(lián)匯編。

payable

payable 關(guān)鍵字用來說明,這個(gè)函數(shù)可以接受以太幣,如果沒有這個(gè)關(guān)鍵字,函數(shù)會(huì)自動(dòng)拒絕所有發(fā)送給它的以太幣。

事件

事件 是合約和區(qū)塊鏈通訊的一種機(jī)制。你的前端應(yīng)用“監(jiān)聽”某些事件,并做出反應(yīng)。例如:

// 這里建立事件
event IntegersAdded(uint x, uint y, uint result);

function add(uint _x, uint _y) public {
  uint result = _x + _y;
  //觸發(fā)事件,通知app
  IntegersAdded(_x, _y, result);
  return result;
}

用戶界面(當(dāng)然也包括服務(wù)器應(yīng)用程序)可以監(jiān)聽區(qū)塊鏈上正在發(fā)送的事件,而不會(huì)花費(fèi)太多成本。一旦它被發(fā)出,監(jiān)聽該事件的listener都將收到通知。而所有的事件都包含了 from , toamount 三個(gè)參數(shù),可方便追蹤事務(wù)。 為了監(jiān)聽這個(gè)事件,你可以使用如下代碼(javascript 實(shí)現(xiàn)):

var abi = /* abi 由編譯器產(chǎn)生 */;
var ClientReceipt = web3.eth.contract(abi);
var clientReceipt = ClientReceipt.at("0x1234...ab67" /* 地址 */);

var event = clientReceipt.IntegersAdded();

// 監(jiān)視變化
event.watch(function(error, result){
    // 結(jié)果包括對 `Deposit` 的調(diào)用參數(shù)在內(nèi)的各種信息。
    if (!error)
        console.log(result);
});

// 或者通過回調(diào)立即開始觀察
var event = clientReceipt.IntegersAdded(function(error, result) {
    if (!error)
        console.log(result);
});
代碼示例

下面是一個(gè)完整的代碼示例:

pragma solidity ^0.4.19;

contract ZombieFactory {

    // 建立事件
    event NewZombie(uint zombieId, string name, uint dna);

    uint dnaDigits = 16;  // 定義狀態(tài)變量
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {  // 定義結(jié)構(gòu)體
        string name;
        uint dna;
    }

    Zombie[] public zombies;  // 定義動(dòng)態(tài)數(shù)組

    // 創(chuàng)建私有函數(shù),私有函數(shù)命名使用 _ 前綴
    function _createZombie(string _name, uint _dna) private {
        // 函數(shù)參數(shù)命名 使用 _ 作為前綴
        // arrays.push() 將元素加入到數(shù)組尾部,并且返回?cái)?shù)組的長度
        uint id = zombies.push(Zombie(_name, _dna)) - 1;
        // 觸發(fā)事件
        NewZombie(id, _name, _dna);
    }

    // view 為函數(shù)修飾符,表示此函數(shù)不需要更新或創(chuàng)建狀態(tài)變量
    // pure 表示函數(shù)不需要使用狀態(tài)變量
    function _generateRandomDna(string _str) private view returns (uint) {
        // 使用 keccak256 創(chuàng)建一個(gè)偽隨機(jī)數(shù)
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
    }

    function createRandomZombie(string _name) public {
        uint randDna = _generateRandomDna(_name);
        _createZombie(_name, randDna);
    }

}
Ethereum 內(nèi)部有一個(gè)散列函數(shù)keccak256,它用了SHA3版本。一個(gè)散列函數(shù)基本上就是把一個(gè)字符串轉(zhuǎn)換為一個(gè)256位的16進(jìn)制數(shù)字。
在智能合約中使用隨機(jī)數(shù)很難保證節(jié)點(diǎn)不作弊, 這是因?yàn)橹悄芎霞s中的隨機(jī)數(shù)一般要依賴計(jì)算節(jié)點(diǎn)的本地時(shí)間得到, 而本地時(shí)間是可以被惡意節(jié)點(diǎn)偽造的,因此這種方法并不安全。 通行的做法是采用 鏈外off-chain 的第三方服務(wù),比如 Oraclize 來獲取隨機(jī)數(shù))。
參考鏈接

Solidity 文檔: https://solidity-cn.readthedocs.io/zh/develop/index.html

cryptozombie-lessons: https://cryptozombies.io/zh/


最后,感謝女朋友支持和包容,比??

也可以在公號輸入以下關(guān)鍵字獲取歷史文章:公號&小程序 | 設(shè)計(jì)模式 | 并發(fā)&協(xié)程

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/24264.html

相關(guān)文章

  • Solidity 簡易教程0x001

    摘要:函數(shù)和可用于檢查條件并在條件不滿足時(shí)拋出異常。函數(shù)只能用于測試內(nèi)部錯(cuò)誤,并檢查非變量。函數(shù)和狀態(tài)變量僅在當(dāng)前定義它們的合約中使用,并且不能被派生合約使用。派生合約可以訪問所有非私有成員,包括內(nèi)部函數(shù)和狀態(tài)變量,但無法通過來外部訪問。 Solidity是以太坊的主要編程語言,它是一種靜態(tài)類型的 JavaScript-esque 語言,是面向合約的、為實(shí)現(xiàn)智能合約而創(chuàng)建的高級編程語言,設(shè)計(jì)...

    FrozenMap 評論0 收藏0
  • 以太坊開發(fā)語言solidity入門

    摘要:什么是以太坊是一種面向智能合約的高級語言,其語法與類似。如果希望快速進(jìn)行以太坊開發(fā),那請看我們精心打造的教程以太坊入門教程,主要介紹智能合約與應(yīng)用開發(fā),適合入門。 這篇關(guān)于Solidity教程的博客展示了很多Solidity特性。本教程假定你對以太坊虛擬機(jī)和編程有一定的了解。 以太坊,世界計(jì)算機(jī)提供了一個(gè)非常強(qiáng)大的全球共享基礎(chǔ)設(shè)施,使用名為Solidity的編程語言構(gòu)建去中心化應(yīng)用程序...

    hqman 評論0 收藏0
  • 以太坊開發(fā)語言solidity入門

    摘要:什么是以太坊是一種面向智能合約的高級語言,其語法與類似。如果希望快速進(jìn)行以太坊開發(fā),那請看我們精心打造的教程以太坊入門教程,主要介紹智能合約與應(yīng)用開發(fā),適合入門。 這篇關(guān)于Solidity教程的博客展示了很多Solidity特性。本教程假定你對以太坊虛擬機(jī)和編程有一定的了解。 以太坊,世界計(jì)算機(jī)提供了一個(gè)非常強(qiáng)大的全球共享基礎(chǔ)設(shè)施,使用名為Solidity的編程語言構(gòu)建去中心化應(yīng)用程序...

    tigerZH 評論0 收藏0
  • 區(qū)塊鏈技術(shù)學(xué)習(xí)指引

    摘要:引言給迷失在如何學(xué)習(xí)區(qū)塊鏈技術(shù)的同學(xué)一個(gè)指引,區(qū)塊鏈技術(shù)是隨比特幣誕生,因此要搞明白區(qū)塊鏈技術(shù),應(yīng)該先了解下比特幣。但區(qū)塊鏈技術(shù)不單應(yīng)用于比特幣,還有非常多的現(xiàn)實(shí)應(yīng)用場景,想做區(qū)塊鏈應(yīng)用開發(fā),可進(jìn)一步閱讀以太坊系列。 本文始發(fā)于深入淺出區(qū)塊鏈社區(qū), 原文:區(qū)塊鏈技術(shù)學(xué)習(xí)指引 原文已更新,請讀者前往原文閱讀 本章的文章越來越多,本文是一個(gè)索引帖,方便找到自己感興趣的文章,你也可以使用左側(cè)...

    Cristic 評論0 收藏0
  • 智能合約語言 Solidity 教程系列6 - 結(jié)構(gòu)體與映射

    摘要:本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接智能合約語言教程系列結(jié)構(gòu)體與映射原文已更新,請讀者前往原文閱讀教程系列第篇結(jié)構(gòu)體與映射。不能聲明一個(gè)同時(shí)將自身作為成員,這個(gè)限制是基于結(jié)構(gòu)體的大小必須是有限的。 本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接:智能合約語言Solidity教程系列6 - 結(jié)構(gòu)體與映射原文已更新,請讀者前往原文閱讀 Solidity 教程系列第6篇 - Solidity 結(jié)構(gòu)體與...

    masturbator 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<