solidity 從入門到實戰(一)
注意:本專欄主要來自于https://www.bilibili.com/video/BV1St411a7Pk?p=11&spm_id_from=pageDriver的學習筆記
撰寫第一個案例
//宣告版本號
pragma solidity ^0.4.16;
//合約 有點類似于java中的class
contract HelloWorld{
//合約屬性變數
string myName = "HelloWorld";
//合約中方法 注意語法順序 其中此處view 代表方法只讀 不會消耗gas
function getName() public view returns(string){
return myName;
}
//可以修改屬性變數的值 消耗gas
function changeName(string _newName) public{
myName = _newName;
}
// pure:不能讀取也不能改變狀態變數
function pureName(string _name) public pure returns(string){
return _name;
}
}
用constant、view、pure修飾function分別表示:
- constant:只能讀取不可改變狀態變數(就是contract中定義的變數)
- view:只能讀取不可改變狀態變數,和constant一樣
- pure:不能讀取也不能改變狀態變數
想要詳細了解他們的區別,請點擊: https://www.jianshu.com/p/5f1bc0d39d79
solidity 語法介紹
注意:由于以下內容都是一些基本的語言特性,相信有編程基礎的同學都可以看懂,因此,關于它的語法代碼可以運行一下,看看效果,這里就不做過多的解釋,
真偽與或非
pragma solidity ^0.4.16;
contract BoolTest{
bool a;
int c = 100;
int d = 200;
function getBoolDefault() returns(bool){
return a;
}
function getBoolean() returns(bool){
return !a;
}
function judge() returns(bool){
return c==d;
}
function logicAnd() returns(bool){
return c==d && true;
}
function logicOr() returns(bool){
return c==d || true;
}
function logicNot() returns(bool){
return c!=d && true;
}
}
整型與算術運算
在solidity中,基本的整型有
int(有符號整型,有正有負)和uint(無符號整型,無負數),并且他們以8位為區間,int支持int8,int16,int24至int256,uint同理,int默認為int256,uint默認為uint256
基本算術運算
pragma solidity ^0.4.16;
contract Math{
//加
function add(uint a,uint b) public returns(uint){
return a+b;
}
//減
function minus(uint a,uint b) public returns(uint){
return a-b;
}
//乘
function multiply(uint a,uint b) public returns(uint){
return a*b;
}
//除
function divide(uint a,uint b) public returns(uint){
return a/b;
}
//取余
function mod(uint a,uint b) public returns(uint){
return a%b;
}
//冪運算
function square(uint a,uint b) public returns(uint){
return a**b;
}
}
位運算
solidity支持的位運算有以下幾種
位與&,位或|,位非~,位異或^,左移>>,右移<<
pragma solidity ^0.4.16;
contract Math{
uint8 a = 3;
uint8 b = 4;
function bitwiseAnd() public returns(uint8){
return a&b;
}
function bitwiseOr() public returns(uint8){
return a|b;
}
function tilde() public returns(uint8){
return ~a;
}
function caret() public returns(uint8){
return a^b;
}
function leftShift() public returns(uint8){
return a<<1;
}
function rightShift() public returns(uint8){
return a>>1;
}
}
復合運算
++和-- 只需要記住
誰在前,結果輸出誰(加號在前,結果加一;數字在前,結果輸出數字本身);而變數本身等于運算后的值,
pragma solidity ^0.4.16;
contract Math{
//輸出a
function add2(uint a) public returns(uint){
return a++;
}
//輸出a+1
function add3(uint a) public returns(uint){
return ++a;
}
//輸出a
function minus2(uint a) public returns(uint){
return a--;
}
//輸出a-1
function minus3(uint a) public returns(uint){
return --a;
}
}
整型溢位及例外處理
我們先看一下以下代碼
pragma solidity ^0.4.16;
contract Math{
function flow() view public returns(uint8){
uint8 mm = 255;
mm++;
return mm;
}
function flow2() view public returns(uint256){
uint8 mm = 255;
mm++;
return mm;
}
function flow3() view public returns(uint){
uint mm = 255;
mm++;
return mm;
}
}
通過運行,我們會發現flow=0,flow2=0, flow3=256,出現這個原因就是因為那就是進位溢位導致,
我們再來看看下面這段代碼
pragma solidity ^0.4.16;
contract Math{
function flowMinus() view returns(uint8){
uint8 nn = 0;
nn--;
return nn;
}
function flowMinus3() view returns(uint8){
uint8 nn = 0;
return nn--;
}
}
上述的復合減運算答案分別是255和0,你猜對了嗎?
要避免的例外
例如:除數不能為0
pragma solidity ^0.4.16;
contract Math{
function errorTest() view returns(int){
int a = 2;
int b = 3;
return a/b;
}
function errorTest2() view returns(int){
int a = 2;
int b = 0;
return a/b;
}
}
陣列
固定長度位元組陣列
關鍵字有:bytes1,bytes2mbytes3,…,bytes32(以步長1遞增),byte代表bytes1,
pragma solidity ^0.4.16;
contract ByteArray{
bytes1 public num1 = 0x7a;
bytes2 public num2 = 0x7a68;
bytes12 public num3 = 0x7a68656e676a69616e78756e;
}
固定長度位元組陣列對于數值來說,有點等同于我們的uint,一個位元組等于8位,即bytes1 有點等同于uint8,至少在位數上是相等的,
**
注意:上面的例子,我們同時引入了一個public修飾合約成員變數的范例,在solidity中,直接用public宣告成員變數,編譯部署后,會為我們生成一個默認的get方法,讓我們可以直接呼叫這個成員屬性,
**
動態長度位元組陣列
pragma solidity ^0.4.16;
contract DynamicByteArray{
bytes public name = new bytes(2);
function initName(){
name[0] = 0x7a;
name[1] = 0x68;
}
function getLength() view returns(uint){
return name.length;
}
function changeName(){
name[0] = 0x88;
}
function changeLength(){
name.length = 5;
}
}
依次執行
getLength,initName,name,changName,name,changeLength,getLength看看結果
此外,我們的動態陣列,還提供了一個push方法,可以在我們自己陣列的末尾繼續添加我們的位元組元素,
function pushTest(){
name.push(0x99);
}
字串
在上節我們學習了動態位元組陣列,而我們的字串,可不可以按照動態位元組的陣列去獲取他的長度和其中的元素呢?
pragma solidity ^0.4.16;
contract DynamicString{
string name = "tongxuejava";
function getLength() returns(uint){
// return name.length; 不能夠直接的獲取string的長度
return bytes(name).length;//通過bytes強轉的轉換
}
function getPartName() returns(bytes1){
return bytes(name)[0];
}
function changeName() {
// return name[0];不能夠直接通過下標的方式獲取string里面的內容
bytes(name)[0] = 'T';
}
}
通過實驗,我們發現要想獲取字串中的元素,得通過
bytes()進行強制轉換,
固定長度位元組陣列轉化
pragma solidity ^0.4.16;
contract DynamicString{
bytes12 name = 0x7a68656e676a69616e78756e;
function changeBytes1() view returns(bytes1){
return bytes1(name);
}
function changeByte2() view returns(bytes2){
return bytes2(name);
}
function changeByte3() view returns(bytes16){
return bytes16(name);
}
}

通過運行,我們可以發現規律:
轉小從頭截取,轉大末尾補零,
固定長度位元組陣列轉動態位元組陣列
pragma solidity ^0.4.16;
contract DynamicString{
bytes12 name = 0x7a68656e676a69616e78756e;
function fixBytesToDynamicBytes() view returns(bytes){
//return bytes(name); 直接轉換為動態位元組陣列是不行的
bytes memory newName = new bytes(name.length);//使用一個for回圈來挨個位元組進行轉換
for(uint i= 0;i < name.length;i++){ //注意uint 無符號整型
newName[i] = name[i];
}
return newName;
}
}
動態長度位元組陣列轉為string
(bytes===>string)
pragma solidity ^0.4.16;
contract Bytes2String{
bytes name = new bytes(2);
function init(){
name[0] = 0x7a;
name[1] = 0x68;
}
function bytesToString() view returns(string){
return string(name);
}
}
固定長度位元組陣列轉string
我們上面都知道了動態長度陣列可以強制轉換為string,那么固定長度陣列可不可以強制轉為string呢?
pragma solidity ^0.4.16;
contract Bytes32ToString{
bytes2 name = 0x7a68;
function bytes32ChangeString() returns(string){
return string(name);
}
}
通過撰寫以上合約,會發現編譯出錯,那么我們該如何轉換呢?
從上面的學習中,我們知道,固定長度位元組陣列可以轉為動態位元組陣列,而動態位元組陣列可以轉為string,所以,這就是我們轉換的思路,
pragma solidity ^0.4.16;
contract Bytes32ToString{
function byts32ToString(bytes32 inputName) view returns(string){
bytes memory newName = new bytes(inputName.length);
for(uint i = 0;i<newName.length;i++){
newName[i] = inputName[i];
}
return string(newName);
}
}
接下來,我們將以上內容做一個總結:
- 動態長度位元組陣列
- bytes的初始化–new bytes
- 獲取bytes的長度和內容
- 修改長度和內容
- string
- 不能夠直接獲取長度和內容
- 需要轉換為bytes獲取長度和內容
- 特殊字符的長度的內容和獲取
- 中文字符占用3個位元組
- 固定長度位元組陣列之間轉換
- 轉小從頭截取,轉大末尾補零
- 固定長度轉可變長度陣列
- 利用new bytes(),然后回圈轉換,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/278921.html
標籤:區塊鏈
上一篇:C++___stack&&queue&&priority_queue
下一篇:挖礦工具-Gminer 配置引數
