您好,登錄后才能下訂單哦!
這篇文章主要介紹“面向老程序員的Solidity知識點有哪些”,在日常操作中,相信很多人在面向老程序員的Solidity知識點有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”面向老程序員的Solidity知識點有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
與Java代碼類似,Solidity代碼會先被編譯成字節碼,然后再由EVM負責執行。從邏輯上來講,可以將以太坊視為一臺計算機,其中的每個EVM節點類似在計算機中執行的進程,分布式賬本則是這臺計算機的存儲。
一旦部署成功,其代碼會被復制到以太坊上其他節點,并可以通過命令查看其源碼。以Truffle開發環境為例:
truffle develop
部署MyCoin合約,deploy
MyCoin.at(地址),從其返回的json對象中的source屬性即可看到合約代碼。
合約部署之后就無法更新,這就給開發者帶來了相當大的挑戰:
如何開發出高質量的合約,盡可能的沒有Bug?
如何設計可升級的合約?
說到程序執行的代價,一般指的都是花多少內存、存儲和CPU時間。但執行以太坊上的代碼,除了這些通常意義的代價之外,還需要真金白銀。這是因為以太坊上的交易確認都是需要花錢的!它們主要是那些改變以太坊狀態的操作,如:
賬戶轉賬
部署合約
合約內的寫操作
而且,與其他系統不同,這些操作的執行結果并不會立刻生效。它們會以交易的形式提交到交易池中等待礦工確認,這便是交易費的由來。并且,這個價格也不是一個固定值,它隨著市場行情的波動上下浮動。如果你的交易長時間沒有結果,那么可以看看是否是因為交易費過低。
關于交易費的行情,可以從最新的交易(https://etherscan.io/txs)中了解。
這也給開發者帶來了挑戰:如何在實現功能的前提下盡可能的降低交易成本?
要在以太坊上進行操作,必需要有以太坊賬戶。當前有兩類賬戶類型:
外部賬戶,可簡單認為是“人類用戶”,有私鑰和余額,交易發送前會用私鑰先簽名。
合約賬戶,合約部署之后,會隨之對應有一個賬戶,由余額和相應的合約狀態數據。它由外部消息來觸發執行。觸發源來自外部賬戶或其他合約賬戶。
這里也帶來了一些關于安全性方面的概念轉變:
私鑰是終極秘密,一定是本地存儲,否則都是不安全的。
由于合約是公開的,誰都可以發起執行。如果要實現“只有xxx才能執行本合約”,必需要在合約內部代碼中進行控制。
合約類似Java中的類,但與類不同之處在于,它的構造函數只會被調用一次,即部署合約的時候。
合約的狀態變量相當于類的實例變量,但同樣是持久化的。并且,mapping只能聲明成狀態變量但可在函數內引用。
變量類型同樣也分值類型和引用類型,其中引用類型包括:數組和結構體,后者給自定義類型提供方案。
函數可以返回一個值或多個值,同時可以指定返回的變量。如:
function arithmetic(uint _a, uint _b) public pure returns (uint o_sum, uint o_product) { o_sum = _a + _b; o_product = _a * _b; }
函數修改器(Modifier)類似AOP中的攔截器,提供了修改函數執行流程的機會,一般用來做驗證和檢查。其中“_”用來將控制流返還給被修改的函數,如下例:
modifier onlySeller() { // Modifier require( msg.sender == seller, "Only seller can call this." ); _;} function abort() public onlySeller { // Modifier usage // ... }
幾個重要的修改器:
payable,接收以太的函數必需加上
view或pure,表示函數不會改變以太坊狀態
事件提供了讓外部應用了解合約狀態變化的途徑,一般使用流程是:
合約內部發出事件
外部應用利用web3監聽事件
可見性:
external,僅適用于函數,表示其可被外部合約或交易調用,但不能被內部調用。
public
函數缺省的可見性,可被內部調用和通過消息調用,
狀態變量,EVM會為其自動產生getter
internal,函數和狀態變量可被當前合約和其子合約調用
狀態變量的缺省可見性
private,函數和狀態變量僅被當前合約調用
合約支持多重繼承。
EVM提供了4種數據位置用來存放數據:
storage,持久化,存儲于整個以太坊
memory,函數的本地內存,非持久化
calldata,函數入參,非持久化
stack,EVM的調用棧
規則:
狀態變量:storage
external函數入參:calldata
函數入參:memory
函數局部變量:
引用類型,缺省為storage,但可被覆蓋
值類型,memory,不可被覆蓋
mapping類型,指向外部的狀態變量
狀態變量之間賦值,將產生獨立副本,即相互更改不受引用。
storage和memory變量之間相互賦值,總產生獨立副本。
memory變量之間賦值
值類型,產生獨立副本
引用類型,指向同一地址
由于合約執行是有成本的,需要警惕循環語句。
對于多重繼承的合約,需要明確指明順序,如:
contract X {}contract A is X {}contract C is A, X {}
fallback函數沒有函數名,無法直接調用,但在兩個情況下會被觸發:
合約中無任何函數匹配調用者發過來的請求時
合約接收以太時,此時,fallback函數需使用payable
由于其無法被外部調用,EVM限制其只能最多消耗2300的gas,若超過,則fallback函數失敗。因此,記得要測試合約的fallback函數是否會超過這個限制。
并且,fallback是安全事故的高發地,需要對其進行必要的安全相關的測試。
接口和抽象合約跟Java中的接口和抽象類差別不大,庫(library)是一段可復用的代碼,在調用它的合約上下文內執行:
它不能用狀態變量
不能繼承或被繼承
不能接收以太
合約拋出異常之后,狀態回滾,當前有3種方式:
require(表達式),若表達式為false,則拋出異常,未使用的gas退回
適合驗證函數的入參
assert(表達式),同上,但未使用的gas不會退回,將全部被消耗
適合驗證內部狀態
revert(),直接拋出異常
鑒于以太坊應用的以下特點,編寫solidity代碼時需要非常小心:
執行消耗真金白銀
合約公開可見,即使是private
合約不可篡改,一旦發布無法變更
常見的編碼套路有:
對于支付,優先采用“取款”,而不是“轉賬”(即send或transfer),避免接收合約惡意fallback函數。
對于支付,采用CDI模式,避免重入問題。即:
檢查 -> 更改本合約狀態 ->支付。
善用Modifier進行權限控制。
使用mapping類型保存合約數據,甚至為了方便升級,單獨分離出兩類:
數據合約,僅包含mapping,保留操作mapping的函數,客觀上類似數據表。
控制合約,僅包含邏輯控制,通過數據合約的接口操作數據。若邏輯有問題,只需升級本合約即可,數據仍然得以保留。
使用代理合約。
最后,也是最省事的方式:使用成熟類庫,如OpenZeppelin。
到此,關于“面向老程序員的Solidity知識點有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。