堅実性学習(1)

1.Solidity Foundation

フレンドリーなリマインダー:すべての文は非常に重要であり、すべてのポイントは詳細です。さらに、このチュートリアルは、特定のプログラミング基盤を持っている人がすぐに始めるのに適してい
ます基本的な構文、整数オーバーフローと例外処理、バイト配列、動的バイト配列、文字列、文字列とバイト配列の変換、Solidityをすばやく始めるのに役立ちます

これが直接コードです

pragma solidity ^0.4.16;

contract Helloworld {
    string Myname = "张三";
    function getName() public view returns(string) {
        return  Myname;
    }
    function setName(string newname) public {
        Myname = newname;
    }
     function pureTest(string _name) public pure returns (string) {
        return _name;
    }
}

ここで使用されているエディターはリミックスWebエディターです。クリックしてリミックスエディターに入ります

以下では、このコードを分析します

Javaでは、すでに多くの基本的な理解があります。そのため、堅牢性を学習するときに、他の言語との違いを学ぶだけで済みます。

  1. 最初の行のプラマはSolidityのコンパイル制御命令であり、コード行は、ソースファイルが0.4.16未満で0.5.0以上のコンパイラによってコンパイルされることを許可されていないことを意味します。範囲は左に閉じて右に開いています

    0.4.16 <=コンパイラバージョン<0.5.0

    この間隔のコンパイラバージョンをコンパイルできます。

  2. javaのクラスに相当するcontractキーワードは、コントラクトを定義します

  3. ビューキーワード、これはソリディティに固有のキーワードです。ソリディティは最終的に契約で使用されるため、関連する関数があり、ビューはこれらの関数の1つであり、ビューはメソッドの変更にのみ使用でき、変更されたメソッドjavaのクラスの属性である状態変数を変更することはできません。ここでは、状態変数はMynameです。ここでは、getName()メソッドがMynameの値を変更しないことがわかります。

  4. このコードを実行するには、最初にgetName関数を呼び出します。その結果、次のRedmixコードの実行結果図は操作の結果を示しています。操作は成功しています。
    ガス1
    この図は燃料消費量を示しています。この番号を覚えておいてください。

  5. setName()メソッドを実行します。このメソッドはパラメーターを渡す必要があります。ここに「LiSi」を渡し、[実行]をクリックしてから、getName()を実行して値を再度取得します。結果は次のようになり
    ここに写真の説明を挿入
    ここに写真の説明を挿入
    ますが、ガス料金が変更されていることがわかります。何?

  6. getName()をクリックして複数回実行すると、燃料レートは同じままで、setName()メソッドを再度実行すると、燃料レートが変化します。

  7. これは、ビューによって変更されたメソッドが状態変数を変更する必要がないため、ガスを消費しないことを示しています。したがって、viewキーワードもガスを節約できます。

  8. 純粋なキーワード、このキーワードによって変更されたメソッドは状態変数へのアクセスを許可しないため、ガスを消費する必要はありません。

  9. bool、&&、||、使用法はjavaとまったく同じなので、ここではあまり説明しません。

  10. uintキーワードは非負の整数型を表し、デフォルトはuint256、256は256ビットを意味します。

8ビット= 1バイト

  1. メソッドのオーバーロードも堅牢にサポートされています
  2. ビット演算子:堅牢性は契約の展開に使用されるため、メモリ要件が高くなります。メモリを節約するには、ビット演算子が非常に重要です。

&:ビットワイズAND(同時に1)は1を取得し、1つ以上は0(0)
|:ビットワイズOR(同時に0)は0を取得し、1つ以上は1(1)
〜:否定、0 1になり、1は0になります(数字の文字列のみが必要です)
^:ビット単位のXOR、同じものは0、差は1
<<:左シフト
。>>:右シフト

上記のすべてのシンボルをテストします。結果はここには示されていません。興味がある場合は、自分で実行できます。


pragma solidity ^0.4.16;
   
   contract BoolTest {
       uint8 a = 4;
       uint8 b = 2;
       
       function plus() public view returns(uint8){
           return a + b;
       }
       function minus() public view returns(uint8){
           return a - b;
       }
       function multiply() public view returns(uint8){
           return a * b;
       }
       function divide() public view returns(uint8){
           return a / b;
       }
       function power() public view returns(uint8){
           return a ** b;
       }
       
       function test1() public view returns(uint8){
           return a&b;
       }
       function test2() public view returns(uint8){
           return a|b;
       }
       function test3() public view returns(uint8){
           return ~b;
       }
       function test4() public view returns(uint8){
           return a^b;
       }
       function test5() public view returns(uint8){
           return a<<1;
       }
        function test6() public view returns(uint8){
           return a>>1;
       }
   }

2.整数オーバーフローと例外処理

  1. 次に、非常に危険な整数オーバーフローの問題を紹介し、コードを添付します。
 function flow() public pure returns(uint8){
           uint8 mm = 255;
           return mm;
       }

私たちは知っています。8ビットのデータ範囲は0〜255であるため、このメソッドはmmの値(255)を返し、操作結果は問題ありません。ここに写真の説明を挿入
次にコードを変更します。変更されたコードは以下のとおりです。

function flow() public pure returns(uint8){
           uint8 mm = 255;
           mm++;
           return mm;
       }

コードを変更すると、mmは256になりますが、256はすでに8ビットの値の範囲を超えているため、エラーが発生します。動作結果:
ここに写真の説明を挿入
mm出力の値が直接0になることがわかります。なぜこのような結果になるのでしょうか。

1 1 1 1、1 1 1 1

上記は8ビットです。これは255のバイナリ表現です。数が1増えると、最後のビットが1増えます。バイナリを研究した友人は、後ろから前に、完全な2が1に入り、最後のビットが1になることを知っています。結果は次のとおりです。

1、0 0 0 0、0 0 0 0

8ビットしか読み取れないので、読み取った後の値は

0 0 0 0、0 0 0 0

この値は0であるため、m以降の8ビットの読み取り値は0になります。

結論を確認するために、コードを再度変更します。

 function flow() public pure returns(uint8){
           uint8 mm = 255;
           mm++;
           mm++;
           return mm;
       }

操作結果:
ここに写真の説明を挿入
前のmmの値に1を加えると、次のようになります。

0 0 0 0、0 0 0 1

したがって、mmの結果は1です。これにより、先ほどの結論が正しいことを確認できます。

  1. 別の関数を書いて、コードを添付してみましょう。
function erroTest() public pure returns(int){
            int a1 = 1;
            int a2 = 0;
            return a1/a2;
        }

上記の機能に注意して、0が除数として使用することはできませんので、我々は渡すために、このコードをコンパイルすることができますが、私たちは、この関数を呼び出すときに、我々は次のフィールドが表示されます、我々は上記の機能にエラーが表示されていることは明らかである。
ここに写真の説明を挿入
これは、例外が発生しました。

注:Solidityは現在、10進タイプをサポートしていません

3.バイト配列

私たちはまだコードの一部を与えます

pragma solidity ^0.4.0;
 
 contract BytesArray {
     
     bytes1 public num1 = 0x7a;// 只有一个字节的数  二进制表示:0111 1010
     bytes2 public num2 = 0x7a68;// 有两个字节的数 二进制表示:0111 1010 0110 1000
     
     function getLength() public returns(uint256) {
          return num1.length;// length属性不可修改
     }
     
     function getLength2() public returns(uint256) {
          return num2.length;// length属性不可修改
     }
 }
  1. バイト配列はストレージ内のintと同じですが、加算、減算、乗算、および除算の操作を直接実行することはできません。ただし、数値(>、> =、==、<=、<)を比較したり、ビット単位の操作(&、|、〜、^、<<、>>)を実行したりすることもできます。
  2. 属性がパブリックとして追加されると、属性を取得するためのgetメソッドがデフォルトで生成されます。
  3. 次のコードを追加して、上記のステートメントを検証します。fは、ビット操作後にそれぞれ&、|、〜、^、<<、>>の値を計算し、戻ります。
 function and() public returns(bytes2 n1,bytes2 n2,bytes2 n3, bytes2 n4, bytes2 n5,bytes2 n6){
          return (num1&num2,num1|num2,~num1,num1^num2,num1<<1,num1>>1);
      }

結果を取得し
ここに写真の説明を挿入
ます。結果は正しいです。

4.動的バイト配列

コード上:

 pragma solidity ^0.4.0;
 
 contract BytesArray {
     
     bytes public name = new bytes(2);
     
     function initName() public {
         name[0] = 0x7a;
         name[1] = 0x68;
     }
     
     function getLength() public returns(uint256){
         return name.length;
     }
     
     function changeLength() public {
         name.length = 5;
     }
 }
  1. initNameを実行した後、name属性の値を確認してください。
    ここに写真の説明を挿入
    結果は問題ありません。

  2. getLength()メソッドを実行して、バイト配列の長さを表示します。

ここに写真の説明を挿入
長さは2で、結果は正しいです

  1. changeLength()メソッドを実行して、バイト配列の長さを変更します。
    ここに写真の説明を挿入
    ここに写真の説明を挿入
    長さは5になります。

概要:動的バイト配列は、配列の長さを変更できます。

  1. name.push(0x99)は、名前の動的バイト配列に0x99の要素を追加します。

4.ストリングタイプ

  1. 文字列の操作は基本的にjavaの操作と同じです。文字列のバランスバイトを強制的に変換できます。この機能を使用して、文字列の特定の位置にある値にアクセスできます。
    コードテスト
pragma solidity ^0.4.0;

contract StringTest {
    string public name = "zhangsan";
    
    function getLength() public returns(uint256){
        return bytes(name).length;
    }
    
    function changeName() public {
        bytes(name)[0] = 'L';
    }
    
    function getCName() public returns(bytes1){
        return bytes(name)[0];
    }
}
  1. 名前を取得:
    ここに写真の説明を挿入
  2. 8バイトの長さを取得します。
    ここに写真の説明を挿入
  3. getCName()を呼び出して最初の文字を取得します
    ここに写真の説明を挿入
    。6。changeNameを呼び出して最初の文字を変更してから、名前を取得します。
    ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_51194902/article/details/112266013