Solid advanced programming | pay attention to the details in the contract

Posted by kaushikgotecha on Fri, 14 Jan 2022 20:15:30 +0100

Supplementary knowledge:

  1. If the transfer is not related to the deployer, it is related to the trader!
  2. Gas is a unit of measurement in Ethereum network. It is an indicator designed to quantify computing power consumption. That is to say, with gas as the unit of calculation, we can easily calculate how much gas costs users need to pay to complete a transaction, and how much gas rewards miners can receive after completing the packaging of a block.

1. Built in global variables

  • msg.sender:

Get the caller's address. The following example is called by the deployer, so it is the deployer's address,
For example, if the a account is deployed, but the b account is used to call the getOwner, then the owner at this time is the address of the b account.

pragma solidity 0.4.22;
contract Owner {
    address public owner;
    function getOwner() public {
        owner = msg.sender;   // Gets the address of the caller
    }
}
  • msg.value:

Can receive the transfer amount modified by payable, unit: wei, and must have payable

The received value can be used for judgment and restriction. For example, the transfer amount must be within a certain range, but balance cannot

pragma solidity 0.4.22;
contract Value {
    uint256 public money;
    function getValue() public payable {
        money = msg.value;
    }
}

If you add if to judge:

pragma solidity 0.4.22;

contract Value {
    uint256 public money;
    function getValue() public payable {
        if( msg.value == 666) {  // The value can only be assigned when the transfer amount is 666wei 
            money = msg.value;
        }
    }
}

Note: you need to transfer money. Note that the default company is wei

Built in global variablesabbreviationtype
blockhashHash valuebyte32
block.coinbaseAddress of the current blockaddress
block.difficultyDifficulty of current blockuint
block.gaslimigaslimit of the current blockuint
block.numberThe block number of the current blockuint
block.timestampTimestamp of the current blockuint
gasleft()Remaining gasuint
msg.senderAddress of the calleraddress
msg.valueAmount transferred (unit: wei)uint
msg.dataComplete call datacalldata bytes
nowTimestamp of the current blockUint (same as block.timestamp)
tx.gaspricegas price of transactionuint
tx.originSender of transactionaddress

2. Error handling

  • require:
    The required exception will not consume any gas. It is officially recommended to use require, which is equivalent to if {throw}. There is no else
    Finally, the underlying trigger is also an assert error
require(msg.value == 666);    // If not, an error will be reported; otherwise, proceed to the next step

Similar to the following: note that the conditions are exactly the opposite

if (msg.value <= 6 * 10 ** 18)  {
    // todo involves error handling
    throw;
}
  • assert:
    Even if there is an error, gas will be executed and deducted
assert(msg.value == 666 );    // If not, an error will be reported; otherwise, proceed to the next step
  • revert(): deal with scenarios with more complex logic, such as if/else
if (msg.value <= 6 * 10 ** 18){
    revert();
} else {
    b = 666;
}
  • Require (condition); If the conditions are met, proceed to the next step. If not, an error will be reported without deducting gas. It is recommended
  • assert (condition); assert deducts gas, which is not recommended
  • Revert(): used in logic, if (condition) {revert();}else{…}

3. Access function

To return a variable, you have to write a function to return

pragma solidity 0.4.22;
contract Hello {
    string name = "hallen";
    function get_name() public view returns(string){
        return name;
    }
}

If the variable is modified with public, an access function with the same name will be generated, which can be accessed directly

pragma solidity 0.4.22;
contract Fan {
    string public name = "fanone";
    function getName() public view returns(string){
        return name;
        // return this.data();  Using this inside the contract also calls the access function
    }
}
contract One {
    function getHelloName() public view returns (string){
        Fan h = new Fan();   // Address direct forced transfer contract type
        return h.name();    // It must be parenthesized here. It is an access function
    }
}

4. Create contract

  • new: the returned address needs to be transferred to the contract type
    This method is used when initializing the contract
Fan h = new Fan();  // Force address directly to contract type

It's a bit like java
The contract variable (Fan public h) is empty at this time. You need to assign an address to use it, otherwise an error will be reported
This method is used in scenarios where the contract type is used as a parameter

Fan public h;
// Assignment in function
address addr = new Fan();
h = Fan(addr); // Assignment address

Transfer syntax:
h.get_money.value(20).gas(800)();

h must be the contract object after the assigned address

pragma solidity 0.4.24;
contract Test1{
    // Get transfer money
    function contractGetMoney() public payable{
    }
    // View balance
    function getBalance() public view returns(uint256){
        return address(this).balance;
    }
}
contract Test2 {
    // View balance
    function getBalance() public view returns(uint256){
        return address(this).balance;
    }
    // Get transfer money
    function contractGetMoney()public payable{
    }
    // Transfer: transfer money to whoever calls it
    Test1 public t1;
    function getAddr(address addr) public{
        t1 = Test1(addr);
    }
    // Transfer money to Test1 contract
    function payToT1() public{
        t1.contract_get_money.value(5 * 10 **18).gas(200)();
    }
    // You have to decorate it with payable and use anonymous functions
    function () public payable {}
}

5. Contractual succession

  • Using the is keyword, multiple parent contracts are separated by commas
    Contract name is parent contract 1, parent contract 2,... {}
    Constraint cat is animal, lactation {} / / lactation: mammal
    If the two parent contracts have the same function, the farthest inheritance principle is followed (the inheritance order is the closest animation and the farthest Lactation, so it is in Lactation)

6. modifier

Before the function is executed, check whether the preconditions are met, and execute the function only when the preconditions are met

pragma solidity 0.4.22;
contract Value {
    uint256 public money;
    modifier check_money(){
        require(msg.value == 10);
        _;  // Modified code refers to all code after entering the function
    }
    function get_value() public payable check_money{  // check_money is the modifier defined above
        money = msg.value;
    }
}

You can combine the constructor to determine whether it is an administrator (deployer). Functions that can only be accessed by administrators can be decorated

pragma solidity 0.4.22;
contract Value {
    address public owner;
    uint256 public money;
    constructor() public{
        owner = msg.sender;
    }
    modifier check_owner(){
        require(msg.sender == owner);
        _;   // Modified code refers to all code after entering the function
    }
    function get_value() public payable check_money{
        money = msg.value;
    }
}

last

Xiaosheng Fanyi, looking forward to your attention.

Topics: Programming Blockchain Bitcoin solidity