區塊鏈智能合約solidity入門

使用ubuntu系統安裝ethereum開發環境php

安裝 Nodejs

sudo apt-get update

sudo apt install curl

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -

sudo apt-get install -y nodejs

sudo apt-get install npm

安裝 ethereumjs-testrpc

sudo apt-get install build-essential

sudo apt-get install git

sudo npm install -g ethereumjs-testrpc

執行testrpc
在整個開發過程當中須要一直雲心testrpc。 每次執行testrpc,都會產生10個帶有test funds的新地址。這些不是真正的錢,咱們能夠放心地進行任何測試而不用損失錢財。
編寫Ethereum智能合約的最流行的語言是solidiy。咱們會使用truffle 開發框架,它能夠幫助咱們建立新的智能合約、編譯、發佈、測試智能合約。node

$ npm install -g truffle

$ mkdir solidity-experiments

$ cd solidity-experiments/

$ truffle init

Truffle會爲建立一個樣例工程而新建一些文件。可使用truffle compile進行編譯。運行truffle migrate來說合約部署到模擬網絡中。git

$ truffle compile
Compiling ConvertLib.sol...
Compiling MetaCoin.sol...
Compiling Migrations.sol...
Writing artifacts to ./build/contracts
$ truffle migrate
Using network 'development'.
Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x686ed32f73afdf4a84298642c60e2002a6d0d736a5478cc8cb22a655ac018a67
  Migrations: 0xa7edbac1156f98907a24d18df8104b5b1bd7027c
Saving successful migration to network...
  ... 0xe3bf1e50d2262d9ffb015091e5f2974c8ebe0d6fd0df97a7dbcde8a0e51c694a
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying ConvertLib...
  ... 0x2e0e6718f01d0da6da2ada13d6e4ad662c5a20e784e04c404e9d4ef1d392bdae
  ConvertLib: 0xf4388ce4d4ce8a443228d65ecfa5149205db049f
  Linking ConvertLib to MetaCoin
  Deploying MetaCoin...
  ... 0xb03a3cde0672a2bd4dda6c01dd31641d95bd680c4e21162b3370ed6db7a5620d
  MetaCoin: 0x4fc68713f7ac86bb84ac1ef1a09881a9b8d4100f
Saving successful migration to network...
  ... 0xb9a2245c27ff1c6506c0bc6349caf86a31bc9f700388defe04566b6d237b54b6
Saving artifacts...

若是遇到# [Truffle Migrate doesn’t work: Error: No network specified. Cannot determine current network] 問題,能夠編輯truffle.js文件web

module.exports = {
   networks: {
   development: {
   host: "localhost",
   port: 8545,
   network_id: "*" // Match any network id
  }
 }
};

編寫第一個Ethereum智能合約

首先咱們編寫一個簡單的ProofofExistence的智能合約。 主要思想就是建立一個數字公證:它存儲了文檔的哈希值做爲存在的證實。使用truffle create contract命令來開始:npm

$ truffle create contract ProofOfExistence1

如今打開contracts/ProofOfExistence1.sol,而後將如下代碼複製到這個文件當中:ubuntu

pragma solidity ^0.4.15;
// Proof of Existence contract, version 1
contract ProofOfExistence1 {
  // state
  bytes32 public proof;
  // calculate and store the proof for a document
  // *transactional function*
  function notarize(string document) {
    proof = proofFor(document);
  }
  // helper function to get a document's sha256
  // *read-only function*
  function proofFor(string document) constant returns (bytes32) {
    return sha256(document);
  }
}

每個合約都有狀態state和函數functions。在智能合約中區分兩種類型的函數是十分重要的:
- 只讀(常量)函數:此函數不會產生任何狀態state改變。它們只會讀取狀態,進行計算,返回值。這些函數會被各類節點在本地計算,不會消耗gas。會被關鍵字constant標記。
- 交易型函數: 會對狀態進行改變的函數。這些改變會在區塊鏈中有所體現,交易型函數須要將交易發送到網絡中,會消耗gas、
下面咱們將ProofOfExistence1部署到網絡中。咱們須要編輯migration 文件migrations/2_deploy_contracts.js 讓truffle來部署新的交易。promise

var ProofOfExistence1 = artifacts.require("./ProofOfExistence1.sol");
module.exports = function(deployer) {
  deployer.deploy(ProofOfExistence1);
};

須要從新運行migrationruby

truffle migrate --reset

和智能合約進行交互

咱們的合約已經部署好了,咱們能夠測試一下。咱們使用函數調用的方式發送消息,讀取public state。咱們可使用truffle console來作這些bash

$ truffle console
// get the deployed version of our contract
truffle(default)> var poe = ProofOfExistence1.at(ProofOfExistence1.address)
// and print its address 
truffle(default)> poe.address
0x3d3bce79cccc331e9e095e8985def13651a86004
// let's register our first "document"
truffle(default)> poe.notarize('An amazing idea')
{ tx: '0x18ac...cb1a',
  receipt: 
   { transactionHash: '0x18ac...cb1a',
     ...
   },
  logs: [] }
// let's now get the proof for that document
truffle(default)> poe.proofFor('An amazing idea')
0xa3287ff8d1abde95498962c4e1dd2f50a9f75bd8810bd591a64a387b93580ee7
// To check if the contract's state was correctly changed:
truffle(default)> poe.proof()
0xa3287ff8d1abde95498962c4e1dd2f50a9f75bd8810bd591a64a387b93580ee7
// The hash matches the one we previously calculated

首先是要獲取部署的合約存入到poe的變量中。而後調用交易函數notarize,它包含了一個狀態的改變。當咱們調用一個交易函數時,咱們得到了一個promise來解析一個交易對象,而不是實際的函數返回。改變EVM的狀態咱們須要支付gas,而後對網絡發送一筆交易。這就是爲何咱們獲得一個交易信息對象做爲promise的結果,指的是這種狀態改變的交易。在這種狀況下,咱們對交易ID不感興趣,因此咱們不用考慮promise。在編寫一個真正的應用程序的時候,咱們須要保存它來檢查生成的交易並捕獲錯誤。網絡

接下來,咱們調用只讀(常量)函數proofFor。必定要使用關鍵字constant來標記只讀函數,不然Truffle將嘗試建立一筆交易來執行他們。這是一種告訴truffle咱們不會和區塊鏈進行交互而僅僅是讀取值。使用這個只讀函數,咱們得到了文檔的哈希值。

咱們如今須要將其與咱們的智能合約的狀態造成對比。要檢查狀態是否正確改變,咱們須要讀取證實公共狀態變量。爲了得到一個公共狀態變量的值,咱們能夠調用一個同名的函數,它返回一個值的Promise。在咱們的例子中,輸出哈希值是相同的。