摘要:舍去小數(shù)位在以太坊中賬戶有兩種類型普通賬戶和智能合約賬戶。報酬是小額的以太幣,想要運行智能合約的人的需要支付報酬來使合約工作。涉及到以太坊智能合約的攻擊的問題。
智能合約可以簡單的理解為一段可執(zhí)行的程序片段,具體的代碼經(jīng)過 Solidity 編寫之后,發(fā)布到區(qū)塊鏈上。而以太坊的智能合約也可以理解為一個特殊的交易(包括可執(zhí)行代碼的),被發(fā)送出去后會被礦工打包記錄在某一個區(qū)塊中,當需要調(diào)用這個智能合約的方法時只需要向這個智能合約的地址發(fā)送一筆交易即可。 因為觸發(fā)的條件和打錢地址都已經(jīng)被編寫在代碼里,存儲在區(qū)塊鏈上,所以可以最大程度的排除人為因素的干擾。
合約的基本結構程序版本(Version Pragma):Solidity 大多都是開源的程序,在代碼中加上程序版本是為了方便社區(qū)合作。描述程序版本的規(guī)則和 npm 的一樣。
pragma solidity ^0.4.19;
合同(contract)聲明:合同類似于面向?qū)ο笳Z言中的類(Class)。
contract SimpleStorage { }
狀態(tài)變量(State variable)聲明:狀態(tài)變量是永久存儲在合同存儲中的值。
contract SimpleStorage { uint storedData; // State variable }
函數(shù)(function)聲明:函數(shù)是合約內(nèi)代碼的可執(zhí)行單元。
contract SimpleStorage { function simpleFn() { } }
返回一個或多個參數(shù)
直接賦值返回的命名參數(shù)
// 返回一個值 function oneParameter() returns(uint){ return 1; } // 返回多個返回值 function twoParameters() returns(uint, uint) { return (1,2); } // 命名參數(shù)直接賦值 function namedParameter() returns(uint foo, uint bar) { foo = 1; bar = 2; } // 獲取返回值 function get() { uint one = oneParameter(); var (two1, two2) = twoParameters(); var (named1, named2) = namedParameter(); }類型
bool:false / true
操作符:! , && , || , == , !=
uinit/int:無符整型、有符整型
操作符:
比較:<= , < , == , >= , >
位計算:& , | , ^ , ~
計算:+ , - , * , / , % , **
注意:
整型除法運行會舍去小數(shù)位。
solidity 暫時沒有浮點數(shù)。有定點數(shù),但支持性不好。
int x = 7/4 // 報錯。計算出來的值是有理數(shù),但 solidity 根本沒有浮點數(shù)等類型來表示有理數(shù),更不能將有理數(shù)轉換為 int 類型。 // 正確方法,需先定義類型 int a =7; int b = 4; int c = a/b; c == 1.75 // 報錯。根本沒有浮點數(shù)。 c == 1 // true。舍去小數(shù)位
address:在以太坊中賬戶有兩種類型:普通賬戶和智能合約賬戶。普通賬戶只存儲 ETH 的賬戶,智能合約賬戶不僅存儲 ETH,同時也有可以運行的代碼。
以太坊地址是 20 字節(jié)的十六進制的值,該值范圍在 2^256 以內(nèi)??梢酝ㄟ^isValidAddress檢測是否有效。
address x = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF function isValidAddress(address) { return /^0x[0-9a-fA-F]{40}$/.test(address) } isValidAddress(x)
成員:
address.banlance (uint256):地址余額,單位 Wei。banlance 的值是 readonly 的,調(diào)用 payable 函數(shù)入賬,調(diào)用 address.transfer() 等出賬,以太坊自動計算新的余額。
address.transfer(uint256 value) :給 address 轉賬 value(Wei),且調(diào)用異常會拋出。
address.send(value):和 transfer 類似,但調(diào)用后的異常將不會被返回,只會返回一個 false。
address.call, address.callcode, address.delegatecall:智能合約相互調(diào)用時使用
注意:在 solidity 源碼中,address 不需要加雙引號。但在 Remix 的對話界面中輸入 address 時,務必加上雙引號,否則會報錯,且報錯的消息非常詭異。
全局變量ether 變量:1 ether 代表數(shù)字 1*10^x18 ,而不是幣的單位。
wei == 1
szabo == 10^12 wei
finney == 10^15 wei
ether == 10^18 wei
時間變量:1 seconds 代表數(shù)字 1,而不是時間的單位。同理 1 years 代表的是數(shù)字 3652460*60, 而不是現(xiàn)實世界中的一年,因為現(xiàn)實世界中有會有 閏秒。如合同中需用到準確的一年,需要外部預言機(oracle)。
1 seconds == 1
1 minutes == 60 seconds
1 hours == 60 minutes
1 days == 24 hours
1 weeks == 7 days
1 years == 365 days
block:塊
block.blockhash(uint blockNumber) returns (bytes32): 傳入 blockNumber,返回塊的哈希值
block.coinbase (address): 挖到當前塊礦工的地址
block.difficulty (uint): 當前塊的難度
block.gaslimit (uint): 當前塊最多的 gas
block.number (uint): 當前塊是第幾個
block.timestamp (uint): 當前塊創(chuàng)建的時間戳
now (uint): block.timestamp 的別名
msg: 當執(zhí)行某一個函數(shù)的時候,函數(shù)想要知道調(diào)用函數(shù)的數(shù)據(jù)信息
msg.data (bytes): 包括函數(shù)名字等等,一些沒有經(jīng)過加工的信息。
msg.gas (uint): 函數(shù)調(diào)用方攜帶的 gas
msg.sender (address): 函數(shù)調(diào)用方的地址
msg.sig (bytes4): 整個 msg.data 的前 4 個 byte
msg.value (uint): 函數(shù)調(diào)用方攜帶的 gas,以 wei 為單位計價。
關鍵詞constant 用于變量: 表明當前變量不可修改。如果修改,編輯器會報錯。
constant 用于函數(shù): 表明當前函數(shù)中,不應該修改狀態(tài)。但要十分小心,因為即便修改了,編譯器也不會報錯。
view : 和 constant 用于函數(shù)時功能一樣。另外使用 Remix 時,可以方便查看函數(shù)返回值。使用 view 時,Remix 會把調(diào)用函數(shù)的輸出值放在函數(shù)右邊顯示,而不是在 details 里。
payable: 表明調(diào)用函數(shù)可以接受以太幣。
this: 指向的是當前合同的 address。
revert(): 函數(shù)執(zhí)行失敗,需要通過調(diào)用 revert() 拋異常告訴函數(shù)調(diào)用方。調(diào)用后恢復合同狀態(tài),并將剩余 gas 返還。等同于 throw。
省幣秘訣當你激活一個智能合約的時候,你在要求整個網(wǎng)絡內(nèi)的每個礦工個體分別執(zhí)行里面的運算。這會花費他們的時間和精力,Gas是你為這項服務向礦工們支付的機制。 報酬是小額的以太幣,想要運行智能合約的人的需要支付報酬來使合約工作。付款款項(單位以太幣)= Gas數(shù)量(單位Gas) x Gas price(單位以太幣/Gas) 智能合約越復雜(計算步驟的數(shù)量和類型,占用的內(nèi)存等),用來完成運行就需要越多Gas。
Gas是由一開始發(fā)起transaction的地址進行支付。再比如"合約A調(diào)用合約B再調(diào)用合約C"這個過程中所產(chǎn)生的所有計算步驟所消耗的Gas也都是由調(diào)用合約A的人來承擔的。
用 fn() 代替 this.fn():通過 this.fn() 調(diào)用函數(shù),在 EVM 底層是通過 msg來調(diào)用合約函數(shù)的。相對于直接調(diào)用 fn() 花費的 gas 更多。
減少重復計算。Solidity 編譯器沒有對重復計算做優(yōu)化,需開發(fā)者手動使用臨時變量保存重復計算的值。
function(int a, int b){ // 錯誤。應該使用 int x = a + b 減少重復計算 if(a + b > 0) { int y = a + b; } }安全
一定要把內(nèi)部變量修改完成之后,再給外部錢。涉及到以太坊智能合約的re-entry攻擊的問題。
frank.transfer(salary); // 錯誤,應該將先修改內(nèi)部變量,再 transfer。 lastPayday = lastPayday + payDuration;其他
合約是中介:由于調(diào)用函數(shù)的動作是在挖礦時執(zhí)行的,所以Solidity 沒有原生定時器,不通過合約本身自動觸發(fā)函數(shù)執(zhí)行。應該將合約看做一個中介,需要外部來觸發(fā)合約函數(shù)的執(zhí)行。
本地狀態(tài)變量聲明提升:類似于 JS 用 val 聲明變量。
contract SimpleStorage { function set(uint data){ if (true) { uint temp = 1; // 本地狀態(tài)變量 } uint temp; // 報錯,因為聲明本地狀態(tài)變量的作用域是函數(shù),而不是 {}。 } }
代碼見/payroll.sol
參考資料:
solidity-notes
第一課問題整理
Lesson 1 補充學習筆記
一個基礎的以太坊介紹
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/24002.html
摘要:和比特幣協(xié)議有所不同的是,以太坊的設計十分靈活,極具適應性。超級賬本區(qū)塊鏈的商業(yè)應用超級賬本超級賬本是基金會下的眾多項目中的一個。證書頒發(fā)機構負責簽發(fā)撤 showImg(https://segmentfault.com/img/bV2ge9?w=900&h=385); 從比特幣開始 一個故事告訴你比特幣的原理及運作機制 這篇文章的定位會比較科普,盡量用類比的方法將比特幣的基本原理講出來...
摘要:另外只能做狀態(tài)變量,不能做本地局部變量。語法聲明映射類型包括類型包括狀態(tài)變量報錯??梢暥戎傅氖?,決定函數(shù)或者狀態(tài)變量的可以被哪些智能合約可見和調(diào)用。狀態(tài)變量可見性沒有。在中,通過來抽象出狀態(tài)變量自增的代碼,并修飾。 Mapping 映射(Mappings):類似于哈希表。mapping 中任何一個可能的 key 都對應著一個 value,它的默認值是default-value 。底層用...
摘要:錯誤檢查拋出異常。用于檢查內(nèi)部錯誤,比如上溢和下溢。由于語言完善的問題,支持狀態(tài)變量之間的轉換,未來可能會取消該限制。注意,只能將變量賦值給狀態(tài)變量,而不是本地變量。因為我們只能在狀態(tài)變量中分配內(nèi)存空間。 錯誤檢查 throw: 拋出異常。已被廢棄。 revert(): 拋出異常,并回滾到調(diào)用前的狀態(tài)。 require(bool): require(false) 拋出異常,并回...
摘要:原文發(fā)表于以太坊智能合約開發(fā)第二篇理解以太坊相關概念很多人都說比特幣是區(qū)塊鏈,以太坊是區(qū)塊鏈。它是以太坊智能合約的運行環(huán)境。是由以太坊節(jié)點提供。以太坊社區(qū)把基于智能合約的應用稱為去中心化的應用。 原文發(fā)表于:以太坊智能合約開發(fā)第二篇:理解以太坊相關概念 很多人都說比特幣是區(qū)塊鏈1.0,以太坊是區(qū)塊鏈2.0。在以太坊平臺上,可以開發(fā)各種各樣的去中心化應用,這些應用構成了以太坊的整個生態(tài)...
摘要:引言給迷失在如何學習區(qū)塊鏈技術的同學一個指引,區(qū)塊鏈技術是隨比特幣誕生,因此要搞明白區(qū)塊鏈技術,應該先了解下比特幣。但區(qū)塊鏈技術不單應用于比特幣,還有非常多的現(xiàn)實應用場景,想做區(qū)塊鏈應用開發(fā),可進一步閱讀以太坊系列。 本文始發(fā)于深入淺出區(qū)塊鏈社區(qū), 原文:區(qū)塊鏈技術學習指引 原文已更新,請讀者前往原文閱讀 本章的文章越來越多,本文是一個索引帖,方便找到自己感興趣的文章,你也可以使用左側...
閱讀 1668·2021-09-26 09:55
閱讀 5292·2021-09-22 15:40
閱讀 2029·2019-08-30 15:53
閱讀 1508·2019-08-30 11:15
閱讀 1726·2019-08-29 15:41
閱讀 1880·2019-08-28 18:13
閱讀 3159·2019-08-26 12:00
閱讀 1681·2019-08-26 10:30