区块链学堂(第一课):区块链引子+智能合约+Solidity

2017-02-23 14:03 来源:巴比特资讯 阅读:6648
相信正在看这篇文章的读者一定已经听说过区块链了,并且也相信区块链是一项前景美妙,甚至是颠覆性的技术。

写在前面的话:

相信正在看这篇文章的读者一定已经听说过区块链了,并且也相信区块链是一项前景美妙,甚至是颠覆性的技术。但是也许同时也会感到困惑,对于区块链虽然有一些大致概念,但是具体到如何应用区块链技术,如何区块链编程就会发现并不是那么容易。那么恭喜你!来对地方了。本教程主要介绍的是区块链技术的一个主要流派:以太坊的编程,希望读者阅读完本书后,可以学会并掌握以太坊及其智能合约的编程,并能够将区块链技术落地到实际的项目开发中去。

最后,自我介绍一下:本人网名“星云”,资深互联网从业人员,区块链技术多年的探索者,以太中文网创始人。欢迎有志在区块链领域开创一片新天地的朋友们互相交流,共同进步。

好了,废话说了够多了,进入正题吧!

区块链引子

区块链到底是什么?

区块链(英:Blockchain) 是一种分布式数据库,起源自比特币,区块链是一串使用密码学方法相关联产生的数据块,每一个数据块中包含了若干次比特币网络交易的信息,用于验证其信息的有效性(防伪)和生成下一个区块。(摘自wiki)

区块链技术的定义:

区块链是一个分布式账本,一种通过去中心化去信任的方式集体维护一个可靠数据库的技术方案。

从数据的角度看:

区块链是一种几乎不可能被更改的分布式数据库, ”分布式“有两个含义,一个是分布式存储,一个是所有参与者共同维护

区块链技术的几个特性

  • (1) 匿名

  • (2)不可篡改和加密安全性

  • (3)无须信任系统

  • (4)分布式去中心化

  • (5)交易透明

引用自

基于以上的几个优点,比特币系统实现了一个自我运行的,成交量数十亿的交易系统,全球化7*24小时稳定的运行了多年。任何两个账户之间的比特币买卖都被忠实的记录在大量冗余的账本上。

在比特币网络中,任何账号都是匿名的,任何账号之间的交易都是不可篡改,且会被记录在每一个节点上。然后通过对挖矿的比特币激励机制,实现了这个网络的自运行,无需任何中心化的交易系统。

以太坊

那么以太坊是什么?

以太坊是一个开源的有智能合约功能的公共区块链平台,通过其专用加密货币以太币提供去中心化的虚拟机(EVM)来处理点对点合约(摘自wiki)

最简单的说法就是:区块链技术+智能合约。

以太坊在继承了区块链技术的基础上,实现了对智能合约的支持,从而使得区块链技术可以和商业化应用结合,并实现项目的落地。

在以太坊的网络中,智能合约也被看做一个特殊的账户,从而使得用户可以通过和该账户进行交易,实现对该账户中的属性和方法的调用。从而从底层技术上支持了智能合约的实现。

技术架构图

智能合约是什么?

之前说过区块链技术的五个特性。以太坊继承了上面这所有的区块链技术的基础上,提供了智能合约的支持。从而使区块链技术从原来的账户与账户之间的交易功能,扩展为一个可以实现智能合约的平台。这个智能合约可以是一个众筹合约,也可以是一个数学公式,或者是一个完全的随机数。

只要智能合约 被部署到以太坊的网络上去,他就天生带有了区块链技术的5个特征,同时因为他是由类javascript的语言撰写,因此可以实现很多复杂的业务逻辑。

本教程主要介绍的就是对智能合约的编程,通过编写符合自己商业逻辑的智能合约,就可以轻松的实现各种基于区块链的项目落地。
下一章,我们将从一个最简单的智能合约入手,给大家快速介绍一下智能合约长什么样?

最简单的智能合约

最简单的一个智能合约


pragma solidity 0.4.9;
contract DemoTypes {
    function f(uint a) returns (uint b) {
    uint result = a * 8;
    return result;
    }
}

以上就是一个最简单的一个智能合约, 该智能合约实现了一个最基本的功能,也就是输入N,返回8*N。
那么我们需要如何执行他呢?这个就涉及到一个很有用的工具,browser-solidity了。

官方地址:https://ethereum.github.io/browser-solidity/#version=soljson-v0.4.9+commit.364da425.js

注意这里目前用到的solidity版本为0.4.9, 因此pragma solidity 后面也要跟上0.4.9版本,否则会报错。

将我们上面的代码贴上去,可以看到结果如下图所示:

这个时候点击红色 Create按钮

就可以将这份最简单的智能合约部署到区块链网络上(内存上的)

在这里我们可以看到几个东西

  1. Trasaction/Execution Cost: 这个代表Create一个合约所消耗的成本,单位为Gas。Gas和Ether币有一个兑换关系,兑换比例由Oracle决定

  2. 这里可以看到我们的合约名称DemoTypes, 注册在了一个地址上面。这个代表该合约已经被挖矿出来了。

  3. 第三个就是我们上方的合约代码,f(n) {return 8 * n}

这个时候我们输入100,然后点击f按钮,我们可以看到结果

这样的结果很清楚

  1. 结果是800,符合预期

  2. 执行f()这个function消耗的Gas Cost是21698+800

上面介绍了一个最简单的智能合约,下一章将给大家介绍智能合约的语言 Solidity。也是全书的重心。

Solidity

在上一篇文章中,我们可以看到 pragma solidity 0.4.9;,

这里的Solidity,就是以太坊智能合约的核心语言Solidity,也是本教程的重点。

Solidity是什么?

Solidity是以太坊智能合约的编程语言,通过编译&部署智能合约,可以实现智能合约的Create、执行和查看,从而实现某些商业应用。

几个简单的Solidity例子

通过以下几个智能合约,我们可以将一些商业应用很好的区块链化,从而实现去中介、去信任、高度透明的商业模型。

在之后的整个教程中,我们会逐步解析Solidity编程,帮助大家快速掌握Solidity这门语言,并且将区块链落地到前端Web页面上

I 实现1+2+3+..+n的求和功能

pragma solidity 0.4.9;
contract Demo1 {
  /*计算从1到N的求和*/
  function f(uint n) returns (uint sum) {
    if (n == 0) throw; uint result = 0;
    for (uint i=0; i<=n; i++) {
      result +=i;
    }
    return result;
  }
}

II 实现一个代币功能,并自带挖矿和转移代币的功能。

pragma solidity ^0.4.0;
contract Coin {
    // The keyword "public" makes those variables
    // readable from outside.
    address public minter;
    mapping (address => uint) public balances;
    // Events allow light clients to react on
    // changes efficiently.
    event Sent(address from, address to, uint amount);
    // This is the constructor whose code is
    // run only when the contract is created.
    function Coin() {
        minter = msg.sender;
    }
    function mint(address receiver, uint amount) {
        if (msg.sender != minter) return;
        balances[receiver] += amount;
    }
    function send(address receiver, uint amount) {
        if (balances[msg.sender] < amount) return;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        Sent(msg.sender, receiver, amount);
    }
}

III 实现一个众筹的智能合约,各个用户可以筹款、筹款成功可以将所得转让给受益人,每个参与众筹者可以获得代币。

pragma solidity ^0.4.2;
contract token { function transfer(address receiver, uint amount){  } }
contract Crowdsale4 {
    address public beneficiary;
    uint public fundingGoal;
    uint public amountRaised;
    uint public deadline;
    uint public price;
    token public tokenReward;
    mapping(address => uint256) public balanceOf;
    bool public fundingGoalReached = false;
    event GoalReached(address beneficiary, uint amountRaised);
    event FundTransfer(address backer, uint amount, bool isContribution);
    bool public crowdsaleClosed = false;
    /* data structure to hold information about campaign contributors */
    /*  at initialization, setup the owner */
    function Crowdsale4 (
        address ifSuccessfulSendTo,
        uint fundingGoalInEthers,
        uint durationInMinutes,
        uint etherCostOfEachToken,
        token addressOfTokenUsedAsReward
    ) {
        beneficiary = ifSuccessfulSendTo;
        fundingGoal = fundingGoalInEthers * 1 ether;
        deadline = now + durationInMinutes * 1 minutes;
        price = etherCostOfEachToken * 1 ether;
        tokenReward = token(addressOfTokenUsedAsReward);
    }
    /* The function without name is the default function that is called whenever anyone sends funds to a contract */
    function () payable {
        if (crowdsaleClosed) throw;
        uint amount = msg.value;
        balanceOf[msg.sender] += amount;
        amountRaised += amount;
        tokenReward.transfer(msg.sender, amount / price);
        FundTransfer(msg.sender, amount, true);
    }
    modifier afterDeadline() { if (now >= deadline) _; }
    /* checks if the goal or time limit has been reached and ends the campaign */
    function checkGoalReached() afterDeadline {
        if (amountRaised >= fundingGoal){
            fundingGoalReached = true;
            GoalReached(beneficiary, amountRaised);
        }
        crowdsaleClosed = true;
    }
    function safeWithdrawal() afterDeadline {
        if (!fundingGoalReached) {
            uint amount = balanceOf[msg.sender];
            balanceOf[msg.sender] = 0;
            if (amount > 0) {
                if (msg.sender.send(amount)) {
                    FundTransfer(msg.sender, amount, false);
                } else {
                    balanceOf[msg.sender] = amount;
                }
            }
        }
        if (fundingGoalReached && beneficiary == msg.sender) {
            if (beneficiary.send(amountRaised)) {
                FundTransfer(beneficiary, amountRaised, false);
            } else {
                //If we fail to send the funds to beneficiary, unlock funders balance
                fundingGoalReached = false;
            }
        }
    }
}

Solidity的简介就到此为止了,后面我们会具体解析这些合约的奥秘

前面说过,智能合约是部署在以太坊的网络上的,那么如何搭建一个以太坊网络呢,就需要官方提供的工具Geth了。下一章会详细说明。

声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。

点击阅读全文