羅韭菜的超詳細(xì)dapp從零實(shí)戰(zhàn)(二)-- 編寫(xiě)智能合約與truffle

使用solidity語(yǔ)言撰寫(xiě)智能合約

  • Ethereum上的智能合約需要使用solidity語(yǔ)言來(lái)撰寫(xiě)迎卤。雖然還有其他能用來(lái)撰寫(xiě)智能合約的語(yǔ)言如Serpent(類(lèi)Python)墩弯、lll(類(lèi)Fortran)

  • 但目前看到所有公開(kāi)的智能合約都是使用solidity撰寫(xiě)。

  • solidity還是比較像Java或C#展融。因?yàn)楹蚃avascript不同窖认,solidity與Java或C#同屬于強(qiáng)類(lèi)型(Strong Type,在定義變數(shù)時(shí)需要指定類(lèi)型)語(yǔ)言愈污、在定義函式(function)時(shí)同樣需指定回傳的類(lèi)型(type)耀态、同樣也需要先編譯才能執(zhí)行。這些特性都是Javascript所不具備的暂雹。

關(guān)于solidity編寫(xiě)智能合約的具體語(yǔ)法參見(jiàn)筆者專(zhuān)題

開(kāi)發(fā)前的準(zhǔn)備

  • 本文將使用當(dāng)前最活躍的智能合約開(kāi)發(fā)框架truffle為基礎(chǔ)來(lái)開(kāi)發(fā)首装。ENS(Ethereum Name Service)也是采用truffle框架。其他選擇還有embark等杭跪。

  • 測(cè)試網(wǎng):test rpc仙逻。 畢竟真實(shí)網(wǎng)絡(luò)需要以太幣,且操作需要等待十幾秒涧尿,性價(jià)比不高系奉。testrpc中也包含了Javascript版本的Ethereum虛擬機(jī)(Ethereum Virtual Machine),因此可以完整地執(zhí)行智能合約姑廉。
    -編譯器: atom缺亮,好處之前說(shuō)過(guò)

環(huán)境準(zhǔn)備

  • node.js (自行安卓)
  • 安裝truffle
$ npm install -g ethereumjs-testrpc truffle
  • 啟動(dòng)testrpc
luoxuedeMBP:~ luoxue$ testrpc
EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)

Available Accounts
==================
(0) 0x48e9abd440ff12f0f5bd457d0205d64a2c047973
(1) 0x14692d8b82328f29016db341c15f59585531ab58
(2) 0x0ff04903afd3dc4791ea5b747804de6cd6c4c513
(3) 0x4d77b3d7cadee90f4c90af72be75bd2ac88a72b5
(4) 0xc66ad1ee63b457047e7102425e657b70105f5eb9
(5) 0xfab642ee1cbacd8fc678c83e821f7d8beda61fec
(6) 0xf76e1c57250b88c1628430d0c04e3b4ecb111c0e
(7) 0xf4994bfce769c16f1631f0609867858a96885917
(8) 0xf31105aee2b095265ea46c51e2644eacbab96cb7
(9) 0x51213b5aa72783e7216b55fc2ecb3104dfd5f465

Private Keys
==================
(0) 77b92fa8bdf4bec94f3ebf67f44fb11ff660911ca64d3aa2c729b689aa8c807b
(1) e1b555743af9cc58fb094349776f944b76ff85663b51d5d6bc4802da2e92c54c
(2) c5180d4154bb2d89eb89335766070dcc8210b25374ef8d71c26f50d002f3c450
(3) 61acc2eaf3fdcecad846cf0507ae8cc07fa03a9bf00a581974c268c6bcba0afd
(4) 7f384dad1148c73257c596bc875ca492e8c6e99bb5f7de6958ea4cfe82a5b9a3
(5) 9796225e8d81a3f72e4fccfe3a562838bf589d4c40fcadbdc85c9b9ad5d5ad4c
(6) b858608913552368f4bdbc33a01f7fc7ec98684b013eab2d8dcb696246cbea56
(7) 3b581c0f56aa9937706cd0e27e7a1ccd45513c71d845ab5b18ff5039c20e9d8a
(8) f5d548c0b0c9974711814937b2d0d8373e244aa265ac2e0174b2b9ec35faa134
(9) 22cb6ad0b97dda82426c04485fca580f25746602bc94950efcb13d10528bf622

HD Wallet
==================
Mnemonic:      marriage artwork corn dentist other feel decrease pride brass flash wire since
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

  • testrpc啟動(dòng)后自動(dòng)建立了10個(gè)帳號(hào)(Accounts),與每個(gè)帳號(hào)對(duì)應(yīng)的私鑰(Private Key)桥言。
  • 每個(gè)帳號(hào)中都有100個(gè)測(cè)試用的以太幣(Ether)萌踱。
  • 要注意testrpc僅運(yùn)行在內(nèi)存中,因此每次重開(kāi)時(shí)都會(huì)回到全新的狀態(tài)号阿。

建立項(xiàng)目

輸入以下命令

luoxuedeMBP:~ luoxue$ cd desktop
luoxuedeMBP:desktop luoxue$ mkdir SmartContractDemo
luoxuedeMBP:desktop luoxue$ cd SmartContractDemo
luoxuedeMBP:SmartContractDemo luoxue$ mkdir hello
luoxuedeMBP:SmartContractDemo luoxue$ cd hello
luoxuedeMBP:hello luoxue$ truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test
luoxuedeMBP:hello luoxue$ ls

目錄結(jié)構(gòu):

  • /contracts:存放智能合約原始代碼的地方
  • /migrations:這是 Truffle用來(lái)部署智能合約的功能并鸵,待會(huì)兒我們會(huì)修改2_deploy_contracts.js來(lái)部署 HelloWorld.sol。
  • /test: 測(cè)試智能合約的代碼放在這里扔涧,支持js 與 sol 測(cè)試园担。
  • truffle.js: Truffle 的設(shè)置文檔

新建HelloWorld.sol
放在contracts里届谈,代碼如下

pragma solidity ^0.4.4;

contract HelloWorld {
  function sayHello() returns (string) {
    return ("Hello World");
  }
}

編譯
現(xiàn)在執(zhí)行truffle compile命令,我們可以將HelloWorld.sol原始碼編譯成Ethereum bytecode弯汰。

luoxuedeMBP:hello luoxue$ cd build
luoxuedeMBP:build luoxue$ ls
contracts
luoxuedeMBP:build luoxue$ cd contracts
luoxuedeMBP:contracts luoxue$ ls
HelloWorld.json Migrations.json
  • 編譯成功艰山,新增了build文件夾,會(huì)在HelloWorld文件夾下面的build/contracts文件夾下面看見(jiàn)HelloWorld.json文件咏闪。


    image.png

部署

  • 復(fù)制migration文件夾中的init文件程剥,創(chuàng)建名為2_deploy_contracts.js的文件,代碼如下:
var HelloWorld = artifacts.require("HelloWorld");
module.exports = function(deployer) {
  deployer.deploy(HelloWorld);
};
  • 使用artifacts.require語(yǔ)句來(lái)取得準(zhǔn)備部署的合約汤踏。使用deployer.deploy語(yǔ)句將合約部署到區(qū)塊鏈上。這邊HelloWorld是contract的名稱(chēng)而不是文件名舔腾。因此可以用此語(yǔ)法讀入任一.sol文件中的任一合約溪胶。

  • 現(xiàn)在執(zhí)行truffle migrate命令

  • 注意!N瘸稀哗脖!需要切換到truffle develop 網(wǎng)絡(luò)下編譯和部署,并且部署文件需要在編譯前寫(xiě)對(duì)扳还,因?yàn)榫幾g即產(chǎn)生一個(gè)合約地址才避,錯(cuò)誤的部署文件會(huì)對(duì)不上
    姿勢(shì)如下:

luoxuedeMBP:HelloWorld luoxue$ truffle develop
省略
truffle(develop)> compile
Compiling ./contracts/HelloWorld.sol...
Compiling ./contracts/Migrations.sol...
Writing artifacts to ./build/contracts

truffle(develop)> migrate
Using network 'develop'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0xad8b447607866b32b1c115156a97f9d247a125d35c14585ac3ed3f9eaa06a528
  Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0
Saving successful migration to network...
  ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying HelloWorld...
  ... 0xae7215511d62acedac6c4880d8578240e73913373eaaf6d0e86253197b35261b
  HelloWorld: 0x345ca3e014aaf5dca488057592ee47305d9b3e10
Saving successful migration to network...
  ... 0xf36163615f41ef7ed8f4a8f192149a0bf633fe1a2398ce001bf44c43dc7bdda0
Saving artifacts...
truffle(develop)> 

獲取合約對(duì)象

  • 通過(guò)web3 來(lái)獲取合約對(duì)象
  • 輸入
// 聲明一個(gè)對(duì)象
truffle(develop)> let contract;
undefined
// 實(shí)例化
// truffle console
truffle(develop)> HelloWorld.deployed().then(instance => contract = instance)

  • 解釋?zhuān)簍ruffle console中預(yù)載了truffle-contract函數(shù)庫(kù),以方便操作部署到區(qū)塊鏈上的合約氨距。

  • 這邊使用HelloWorld.deployed().then語(yǔ)句來(lái)取得HelloWorld合約的Instance(實(shí)例)桑逝,并存到contract變量中,以方便后續(xù)的調(diào)用俏让。

  • 使用的是js es6+語(yǔ)句

調(diào)用合約函數(shù)

truffle(develop)> contract.sayHello()
'Hello World'
  • 注意如果該函數(shù)沒(méi)有constant 或者pure 楞遏,需要.call()
    如將代碼增加一個(gè)函數(shù)無(wú)pure/constant如下:
pragma solidity ^0.4.4;

contract HelloWorld {
  // 能直接調(diào)用
  function sayHello() pure public returns (string) {
    return ("Hello World");
  }
  // 需要依靠.call調(diào)用
  function test() public returns (string) {
    return ("Hello World");
  }
}
  • 重新編譯與部署, 注意部署時(shí)候需要加上-- reset
 // 編譯
truffle(develop)> compile
Compiling ./contracts/HelloWorld.sol...

Compilation warnings encountered:

/Users/luoxue/Desktop/SmartContractDemo/HelloWorld/contracts/HelloWorld.sol:9:3: Warning: Function state mutability can be restricted to pure
  function test() public returns (string) {
  ^ (Relevant source part starts here and spans across multiple lines).

Writing artifacts to ./build/contracts
// 部署
truffle(develop)> migrate
Using network 'develop'.

Network up to date.
truffle(develop)> migrate --reset

正確的調(diào)用姿勢(shì)

truffle(develop)> contract.sayHello()
'Hello World'
truffle(develop)> contract.test.call()
'Hello World'
truffle(develop)> 
  • 輸入與輸出,在代碼里面加入一個(gè)echo函數(shù)首昔,輸入字符串寡喝,返回輸出
function echo(string s) public returns (string) {
    return s;
  }
truffle(develop)> contract.echo.call("melody")
'melody'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市勒奇,隨后出現(xiàn)的幾起案子预鬓,更是在濱河造成了極大的恐慌,老刑警劉巖赊颠,帶你破解...
    沈念sama閱讀 223,126評(píng)論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件格二,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡巨税,警方通過(guò)查閱死者的電腦和手機(jī)蟋定,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)草添,“玉大人驶兜,你說(shuō)我怎么就攤上這事。” “怎么了抄淑?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,941評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵屠凶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我肆资,道長(zhǎng)矗愧,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,294評(píng)論 1 300
  • 正文 為了忘掉前任郑原,我火速辦了婚禮唉韭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘犯犁。我一直安慰自己属愤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布酸役。 她就那樣靜靜地躺著住诸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪涣澡。 梳的紋絲不亂的頭發(fā)上贱呐,一...
    開(kāi)封第一講書(shū)人閱讀 52,874評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音入桂,去河邊找鬼奄薇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛事格,可吹牛的內(nèi)容都是我干的惕艳。 我是一名探鬼主播,決...
    沈念sama閱讀 41,285評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼驹愚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼远搪!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起逢捺,我...
    開(kāi)封第一講書(shū)人閱讀 40,249評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谁鳍,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后劫瞳,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體倘潜,經(jīng)...
    沈念sama閱讀 46,760評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評(píng)論 3 343
  • 正文 我和宋清朗相戀三年志于,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涮因。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,973評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伺绽,死狀恐怖养泡,靈堂內(nèi)的尸體忽然破棺而出嗜湃,到底是詐尸還是另有隱情,我是刑警寧澤澜掩,帶...
    沈念sama閱讀 36,631評(píng)論 5 351
  • 正文 年R本政府宣布购披,位于F島的核電站,受9級(jí)特大地震影響肩榕,放射性物質(zhì)發(fā)生泄漏刚陡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評(píng)論 3 336
  • 文/蒙蒙 一株汉、第九天 我趴在偏房一處隱蔽的房頂上張望筐乳。 院中可真熱鬧,春花似錦乔妈、人聲如沸哥童。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,797評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至匀泊,卻和暖如春优训,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背各聘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,926評(píng)論 1 275
  • 我被黑心中介騙來(lái)泰國(guó)打工揣非, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人躲因。 一個(gè)月前我還...
    沈念sama閱讀 49,431評(píng)論 3 379
  • 正文 我出身青樓早敬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親大脉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子搞监,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容