原文標題:
作者:Vivek Singh
翻譯:去中心化金融社區
什麼是Soilidity?
Solidity是一種面向合約的高級編程語言,用於實現智能合約。Solidity已經被設計用於以太坊虛擬機。
Solidity===智能合約。
Solidity的代碼封裝在合約中。合約是以太坊應用程序的基本構建塊——所有變數和函數都屬於一個合約,這將是所有項目的起點。
pragma solidity >=0.5.0 <0.6.0;
contract HelloWorld {
}
在上面的代碼中,我們提供了考慮到我們的代碼與b/w 0.5到0.6的任何版本兼容的版本。我們還創建了一個名為「HelloWorld」的合約。
狀態變數和整數
狀態變數永久存儲在合約存儲中。這意味著它們被寫入以太坊區塊鏈。可以把它們想像成寫入DB。
contract Example {
// This will be stored permanently in the blockchain
uint myUnsignedInteger = 100;
string name = “vivek”
}
Uint數據類型是一個無符號整數。它應該是非負的。
數據類型
值類型:
Boolean(true / false),Integers(int / uint), Address(以太坊地址的大小),String, enum
引用類型:
數組、結構、映射
數學運算
結構
類似於C語言中的struct。當我們需要創建具有多個屬性的複雜數據類型時,我們使用結構體。
struct Person {
uint age;
string name;
數組
數據的集合稱為數組。兩種類型:固定數組和動態數組。
顧名思義,固定數組有預定義的大小,而動態數組沒有大小。
// Array with a fixed length of 2 elements:
uint[2] fixedArray;
// another fixed Array, can contain 5
strings: string[5] stringArray;
// a dynamic Array — has no fixed size, can keep growing:
uint[] dynamicArray;
我們可以組合結構和數組。創建一個結構,然後擁有一個結構數組。就像在面向對象範例(如Java)中有一個對象和一個對象數組一樣。
pragma solidity >=0.5.0 <0.6.0;
contract StudentFactory {
struct student {
string name;
uint roll; } student[] public students; // creates an array named students of student type objects
函數聲明
function eatHamburgers(string memory _name, uint _amount) public { }
函數的可見性是公開的。有兩種方式可以傳遞參數給Solidity函數:
按值和按引用
eatHamburgers(「vitalik」, 100);
私人/公共函數
在Solidity中,函數默認是公共的,因此任何人都可以在網路中調用公共函數。然而,出於安全考慮,我們將函數設為私有,這樣只有所有者才能調用函數。
function _eatHamburgers(string memory _name, uint _amount) private {
}
按照慣例,私有函數的開頭帶有下劃線。
內部/外部關鍵字
還有兩種類型的函數可見性。內部類似於私有,除了它可以被繼承的合約訪問,即繼承。
外部類似於公共。除了聲明了這個函數的聯繫人之外,所有的合約都可以調用這個函數。
在函數中返回
函數聲明包含返回值的類型。
function sayHi() public view/pure returns (string memory) {
return 「Hi」;
}
這些函數可以標記為pure/view。當我們甚至沒有訪問傳遞的數據時,我們就將函數標記為pure。如果函數不修改數據,只查看數據,那麼它將被標記為view。
類型轉換
數據類型之間的轉換稱為類型轉換。
uint8 a = 5;
uint b = 6;
// line below throws an error because a*b returns a uint, not uint8:
uint8 c = a * b;
// we have to typecast b as a uint8 to make it work:
uint8 c = a * uint8(b);
事件
事件用於向前端傳達後端區塊鏈網路上發生了一些事情。
// declare the event
event NotifyOnFrontend(uint x);
function add(uint _x, uint _y) public returns (uint) {
uint result = _x + _y;
//fire an event to let the frontend know the function was called
emit NotifyOnFrontend(result);
return result;
}
我們的前端代碼應該已經安裝了web3,並且應該監聽「NotifyOnFrontend」事件,這樣才能工作。我們的JavaScript框架或普通JS將不得不監聽這個事件來接收它:
YourContract.NotifyOnFrontend(function(error, result) {
// do something with result
})
映射
這是存儲有組織數據(如數組和結構)的另一種方法
mapping (address => uint) public accountBalance;
這是一個鍵值存儲。address是鍵,accountBalance是值。
這可以用於在區塊鏈中存儲多個對象(數據)。檢查示例如下:
例子:
contract Example {
struct UserInfo {
unit age; string dob;
}
mapping(string => UserInfo) allusers;
function setUserInfo(string _name, uint _age, string _dob) public {
allusers[_name].age = _age;
allusers[_name].dob = _dob;
}
function getUserInfo(string name) public view returns(uint, string) {
return (allusers[name].age, allusers[_name].dob);
}
}
現在,如果可以用不同的值多次調用setUserInfo,比如:
setuserInfo(“Vivek”,26, 25/05/1995) setuserInfo(“Supu”, 23, 01/09/1998)
要獲得這些值,只需傳遞名稱:
getUserInfo(“Vivek”); // 26 25/05/1995
getuserInfo(“Supu”); // 24 01/09/1998
全局變數
這些變數可用於像msg.sender這樣的所有函數。我們所編寫的任何Solidity程序,都應該由所有者調用。發送者的地址存儲在msg.sender 全局變數中。
require
require用於驗證這兩個語句,並據此做出決定。如果條件為真,則代碼成功運行,否則就拋出錯誤
function sayHi(string memory name) public returns (string memory) { /Compares if _name equals 「Vivek」 Throws an error and exits if not true. Solidity doesn』t have native string comparison, so we compare their keccak256 hashes to see if the strings are equaq /
require(keccak256(abi.encodePacked(name)) == keccak256(abi.encodePacked(「Vivek」)));
// If it』s true, proceed with the function:
return 「Hi!」;
}
sayHi(「Vivek」) // executes successfully
sayHi(「Supu」) // throws an error
因此,require對於在運行函數之前驗證某些條件必須為真非常有用。
繼承
有時候,與其制定一個非常長的合約,還不如將代碼邏輯拆分為多個合約來組織代碼。
contract Animal {
function catchphrase() public returns (string memory) {
return 「Animal」;
}
} contract Cat is Animal {
function anotherCatchphrase() public returns (string memory) {
return 「Cat is an Animal」;
}
}
import
將代碼拆分為多個文件,並使用import來使用另一個文件中的功能。
這通常是在Solidity項目中處理長代碼庫的方式。
存儲和內存
存儲是指永久存儲在區塊鏈上的變數。內存變數是臨時的,在對合約的外部函數調用之間會被刪除。可以把它想像成電腦的硬碟與內存。
與區塊鏈網路中的其他合約交互
關於這一點,我將寫一篇單獨的文章。現在,保持簡短:
為了與其他合約交互,我們聲明了一個類似object的介面。我們創建了一個合約,並在裡面聲明了一個函數,我們想要從另一個合約調用或使用它。函數只是骨架,它不包含主體。
contract GetNumber {
function getNum(uint _num) public returns(uint){
return _num;
}
假設有一個合約,我們想要使用上面的getNum函數。為此,我們將在項目中創建一個合約,並聲明一個getNum函數框架(沒有函數體)。
contract NumberInterface {
function getNum(uint _num) public returns(uint);
}
現在我們可以從NumberInterface合約中調用getNum函數。
在將合約部署到以太坊後,它就變成了不可變的,也就是說它不能被修改。部署到合約中的初始代碼將永久地停留在區塊鏈上。這就是安全性在Solidity中如此重要的原因之一。如果我們的合約代碼中有一個缺陷,就沒有辦法在以後修補它。必須告訴我們的用戶開始使用具有修復功能的不同智能合約地址。
函數修飾符
函數修飾符看起來就像函數,但是使用關鍵字修飾符而不是關鍵字函數。這些用於特殊情況,例如當您只希望您的所有者而不是所有人做某事時。
這有助於更新DApp的關鍵部分,同時防止其他用戶破壞我們的合約。我處理過的一個用例是——當我們想在執行任何用例之前驗證語句時。
gas
用戶支付gas費來在以太坊網路上運行合約。gas以以太(以太坊上的貨幣)為單位計算。我們的函數的總gas成本等於它所有單獨操作的總gas成本。
更多關於存儲的內容
存儲內存被永久寫入到區塊鏈中。全世界成千上萬的節點需要將這些數據存儲在它們的硬碟上,並且隨著區塊鏈的增長,這些數據量也會隨著時間的推移而增長。所以這樣做是有代價的。
為了降低成本,我們希望避免將數據寫入存儲,除非絕對必要。有時,這涉及到看似低效的編程邏輯——比如每次調用函數時都要在內存中重新構建數組,而不是簡單地將該數組保存在全局存儲變數中以便快速查找。
因此,建議儘可能使用內存類型,這樣數據就不會永久存儲,從而節省成本。循環在Solidity中將比使用存儲更便宜。所以儘可能for 循環中使用內存。這與Java、Python等語言中所做的完全相反,因為for循環的計算成本更高。
For循環
Syntax類似於Javascript。
for (uint i = 1; i <= 10; i++) { // body }
應付修飾符
支付功能是使Solidity和以太坊如此酷的部分原因——它們是一種可以接收以太坊的特殊類型的功能。當我們在一個普通的web伺服器上調用一個API函數時,我們不能在調用函數的同時發送美元——也不能發送比特幣。
但在以太坊中,因為貨幣(以太坊)、數據(交易有效載荷)和合約代碼本身都在以太坊上,所以我們可以同時調用一個函數並向合約支付費用。
這允許一些非常有趣的邏輯,比如為了執行一個函數,需要向合約支付一定的費用。
注意:
在以太坊中,當我們在合約上調用一個函數時,我們將其作為交易廣播到網路上的一個或多個節點。節點在網路上收集一些交易,試圖成為第一個解決計算密集型數學問題的「工作證明」,然後將這組交易連同他們的工作證明(PoW)發布為一個塊到網路的其餘部分。
代幣
所以基本上,代幣只是一個合約,它記錄了誰擁有多少代幣,以及一些函數,以便這些用戶可以將他們的代幣轉移到其他地址。
assert 與 require 的差異
Assert類似於require,如果為false則拋出錯誤。assert和require之間的區別是,當一個函數失敗時,require會退還用戶剩餘的gas,而assert不會。
Metamask
這是Chrome和Firefox的瀏覽器擴展,允許用戶安全地管理他們的以太坊賬戶和私鑰,並使用這些賬戶與使用Web3.js的網站進行交互。
應用程序二進位介面。
在部署的合約之後,它會在以太坊上得到一個固定的地址,在那裡它將永遠存在。在以太坊網路中部署智能合約後,還會生成一個ABI。基本上,它是以JSON格式表示的合約方法,告訴Web3.js如何以我們的合約能夠理解的方式格式化函數調用。
Web3Js
以太坊的JS前端庫被稱為web3.js。
冷萃財經原創,作者:awing,轉載請註明出處:https://www.lccjd.top/2021/12/04/%e8%a7%a3%e6%9e%90soilidity%ef%bc%9a%e7%94%a8%e4%ba%8e%e5%ae%9e%e7%8e%b0%e6%99%ba%e8%83%bd%e5%90%88%e7%ba%a6%e7%9a%84%e9%ab%98%e7%ba%a7%e7%bc%96%e7%a8%8b%e8%af%ad%e8%a8%80/?variant=zh-tw
文章評論