區塊鏈智慧合約solidity入門
使用ubuntu系統安裝ethereum開發環境
安裝 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 開發框架,它可以幫助我們建立新的智慧合約、編譯、釋出、測試智慧合約。
$ npm install -g truffle
$ mkdir solidity-experiments
$ cd solidity-experiments/
$ truffle init
Truffle會為建立一個樣例工程而新建一些檔案。可以使用truffle compile進行編譯。執行truffle migrate來講合約部署到模擬網路中。
$ 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檔案
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // Match any network id
}
}
};
編寫第一個Ethereum智慧合約
首先我們編寫一個簡單的ProofofExistence的智慧合約。 主要思想就是建立一個數字公證:它儲存了文件的雜湊值作為存在的證明。使用truffle create contract命令來開始:
$ truffle create contract ProofOfExistence1
現在開啟contracts/ProofOfExistence1.sol,然後將以下程式碼複製到這個檔案當中:
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來部署新的交易。
var ProofOfExistence1 = artifacts.require("./ProofOfExistence1.sol");
module.exports = function(deployer) {
deployer.deploy(ProofOfExistence1);
};
需要重新執行migration
truffle migrate --reset
和智慧合約進行互動
我們的合約已經部署好了,我們可以測試一下。我們使用函式呼叫的方式傳送訊息,讀取public state。我們可以使用truffle console來做這些
$ 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。在我們的例子中,輸出雜湊值是相同的。