(5) 基于以太坊智能合約的Dapp開發(fā)與實踐 - 智能合約

4,智能合約

4.1 EVM基礎(chǔ)

賬戶

以太坊中有兩種不同類型但是共享同一地址空間的賬戶:外部賬戶由一對公私鑰控制,合約賬戶由賬戶內(nèi)部的合約代碼控制。

外部賬戶的地址是由公鑰(經(jīng)過hash運算)決定的,而合約賬戶的地址在此合約被創(chuàng)建的時候決定的(由合約創(chuàng)建者的地址和發(fā)送到此合約地址的交易數(shù)決定,這就是所謂的“nonce”)不管是哪種類型的賬戶,EVM的處理方式是一樣的
每個賬戶都有一個持久的key-value類型的存儲,把256字節(jié)的key映射到256字節(jié)的value
此外,每個賬戶都有以“Wei”為單位,在交易過程中會被修改的資產(chǎn)(balance)信息

交易

交易是一個從賬戶發(fā)往另一個賬戶(可以是同一個賬戶或者是special zero-account)的消息。它包含二進(jìn)制數(shù)據(jù)(交易相關(guān)的數(shù)據(jù))and Ether。
如果目標(biāo)賬戶包含代碼,代碼會被執(zhí)行,交易相關(guān)的數(shù)據(jù)將作為參數(shù)
如果目標(biāo)賬戶是地址為0的賬戶zero-account, 交易會創(chuàng)建一個新的合約。如上文提到的,合約地址不是一個地址為0的地址,而是一個由交易發(fā)送者和交易數(shù)來決定的地址。這樣的一筆(到zero-account)交易的相關(guān)參數(shù)會被轉(zhuǎn)化為EVM字節(jié)碼然后被執(zhí)行,輸出結(jié)果就是被永久存儲的合約代碼。這意味著為了創(chuàng)建一個合約,并不需要發(fā)送真實的合約代碼,代碼可以被自動創(chuàng)建

費用

創(chuàng)建之后,每筆交易都需要一定數(shù)量的費用,用于限制交易所消耗的工作量,即交易是需要付出代價的(避免DDoS攻擊)。EVM執(zhí)行交易的過程中,費用會按一個特殊規(guī)則逐漸減少
費用的多少是由交易發(fā)起者設(shè)置,至少需要從發(fā)起賬戶支付gas_price * gas用費。如果交易執(zhí)行完畢費用還有剩余的,將退回到發(fā)起賬戶。
如果交易完成之前費用耗盡,將會拋出一個out-of-gas的異常,所有的修改都會被回滾

Storage,Memory,Stack

每個賬戶都有一個持久的內(nèi)存空間,稱之為storage,storage以key-value形式存儲,256字節(jié)的key映射到256字節(jié)value,合約內(nèi)部不可能枚舉storage(內(nèi)部元素),讀取或者修改storage操作消耗都很大(原文是 It is not possible to enumerate storage from within a contract and it is comparatively costly to read and even more so, to modify storage. )。 合約只能讀取和修改自己的storage里的數(shù)據(jù)。
第二種內(nèi)存空間稱之為memory,里面存儲著每個消息調(diào)用時合約創(chuàng)建的實例。memory是線型的,可以以字節(jié)級別來處理,但是限制為256字節(jié)寬度,寫入可以是8或256字節(jié)寬度。當(dāng)讀取或?qū)懭胍粋€預(yù)先未觸發(fā)的指令的時候會消耗memory的空間,消耗空間的同時,必須支付費用(gas)。memory消耗的越多,手續(xù)費越多(按平方級增長)
EVM不是一個注冊的機(jī)器而是一個堆棧機(jī)器,所以所有的計算指令都在stack空間里面執(zhí)行。stack最多只能容納1024個長度不超過256字節(jié)的指令元素。只能用下述方法,從頂部訪問stack:可以拷貝最頂部的16個元素中的一個到stack的最頂部,或者將最頂部的那個元素與其下面的16個元素之一互換。所有其它操作從stack最頂部取出兩個(或一個,或更多,取決于操作)元素,然后把結(jié)果push到stack頂端。當(dāng)然將stack中的元素移到memory或者storage也是可以的,但是不能直接訪問stack中間的元素(必須從頭部開始訪問)

4.2 Solidity代碼實例

pragma solidity ^0.4.18;

contract Ballot{

    address founder;  // who found this contract

    struct Proposal{

        string name;

        uint count;  // count ballot

    }

    Proposal[] public proposals;  // All proposals

    mapping(address => uint8) voters;

    function Ballot() public {

        founder = msg.sender;

    }

    // Only founder could active voter

    function activeVoter(address voterAddr) public{

        if (founder != msg.sender){

            return;

        }

        if(voters[voterAddr] == 0){

            voters[voterAddr] = 1;

        }

        return;

    }

    // Only founder could active proposal

    function activeProposal(string proposalName) public{

        if (founder != msg.sender){

            return;

        }

        for (uint index = 0; index < proposals.length; index++){

            if(keccak256(proposals[index].name) == keccak256(proposalName)){

                return;

            }

        }

        proposals.push(Proposal({

            name: proposalName,

            count: 0 }));

        return;

    }

    // Any activated voter could vode

    function vote(string proposalName) public {

        address voter = msg.sender;

        if(voters[voter] != 1){

            return;

        }

        for(uint index = 0; index < proposals.length; index ++){

            if(keccak256(proposals[index].name) == keccak256(proposalName)){

                proposals[index].count++;

                voters[voter] = 2;

                return;

            }

        }

        return;

    }

    // Anyone could check who is getting the most votes

    function getWinner() public constant returns(string winnerName, uint winnerCount) {

        winnerCount = 0;

        winnerName = "";

        for(uint index = 0; index < proposals.length; index ++){

            if(proposals[index].count > winnerCount){

                winnerName = proposals[index].name;

                winnerCount = proposals[index].count;

            }

        }

    }

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容