Web3dAppDevCamp

發布於 2021-12-11到 Mirror 閱讀

Get & Set Value 3.0 | Web3.0 dApp Dev 0x06

In PurposeHandler version 2.0, we learned to add permission control to functions via the require statement.

Now we can add a real economy mechanism to it, so that the value of purpose is controlled by a real bidding auction mechanism!

0x01 Add Owner

To get the owner of a contract owner is a must-learn operation for newbies.

The easiest way is to set a public owner variable and pass the _owner parameter in the constructor.

pragma solidity >=0.8.0 <0.9.0;
//SPDX-License-Identifier: MIT

contract PurposeHandler {

  string public purpose = "Building Unstoppable Apps";
  address public owner = owner;
  // fill in your own address (start with 0x) here

  constructor(address _owner) {
    owner = _owner;
  }

  function setPurpose(string memory newPurpose) public {
      // about msg.sender:
      // https://cryptozombies.io/en/lesson/2/chapter/3
      // about require:
      // https://cryptozombies.io/en/lesson/2/chapter/4
      require( msg.sender == owner, "NOT THE OWNER!");

      purpose = newPurpose;
      console.log(msg.sender,"set purpose to",purpose);
  }
}

In production, this is generally achieved by importing ownable.sol.

ownable.sol in OpenZepplin.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol

ownable.sol:

pragma solidity ^0.4.25;

  /**
  * @title Ownable
  * @dev The Ownable contract has an owner address, and provides basic authorization control
  * functions, this simplifies the implementation of "user permissions".
  */
  contract Ownable {
    address private _owner;

    event OwnershipTransferred(
      address indexed previousOwner,
      address indexed newOwner
    );

    /**
    * @dev The Ownable constructor sets the original `owner` of the contract to the sender
    * account.
    */
    constructor() internal {
      _owner = msg.sender;
      emit OwnershipTransferred(address(0), _owner);
    }

    /**
    * @return the address of the owner.
    */
    function owner() public view returns(address) {
      return _owner;
    }

    /**
    * @dev Throws if called by any account other than the owner.
    */
    modifier onlyOwner() {
      require(isOwner());
      _;
    }

    /**
    * @return true if `msg.sender` is the owner of the contract.
    */
    function isOwner() public view returns(bool) {
      return msg.sender == _owner;
    }

    /**
    * @dev Allows the current owner to relinquish control of the contract.
    * @notice Renouncing to ownership will leave the contract without an owner.
    * It will not be possible to call the functions with the `onlyOwner`
    * modifier anymore.
    */
    function renounceOwnership() public onlyOwner {
      emit OwnershipTransferred(_owner, address(0));
      _owner = address(0);
    }

    /**
    * @dev Allows the current owner to transfer control of the contract to a newOwner.
    * @param newOwner The address to transfer ownership to.
    */
    function transferOwnership(address newOwner) public onlyOwner {
      _transferOwnership(newOwner);
    }

    /**
    * @dev Transfers control of the contract to a newOwner.
    * @param newOwner The address to transfer ownership to.
    */
    function _transferOwnership(address newOwner) internal {
      require(newOwner != address(0));
      emit OwnershipTransferred(_owner, newOwner);
      _owner = newOwner;
    }
  }

0x02 Create auction mechanism by a require rule

The rule is that if the bid is higher than the current price, then the value of set-purpose can be modified; if it is not as high as the current price, then an error is thrown.

pragma solidity >=0.8.0 <0.9.0;
//SPDX-License-Identifier: MIT

contract PurposeHandler {

  string public purpose = "Building Unstoppable Apps";
  address public owner = owner;
  uint256 public price = 0.001 ether;
  // fill in your own address (start with 0x) here

  constructor(address _owner) {
    owner = _owner;
  }

  function setPurpose(string memory newPurpose) payable public {
      require( msg.value > price, "NOT ENOUGH!");
      purpose = newPurpose;
      // update price when guy set
      price = msg.value;
      console.log(msg.sender,"set purpose to",purpose);
  }

}

0x03 Withdrawal mechanism

The function getBalance() allows the owner to get the balance in the contract, and the function getMyMoney allows the balance in the contract to be withdrawn by.

pragma solidity >=0.8.0 <0.9.0;
//SPDX-License-Identifier: MIT

contract PurposeHandler {

  string public purpose = "Building Unstoppable Apps";
  address public owner;
  uint256 public price = 0.001 ether;

  constructor(address _owner) {
    owner = _owner;
  }

  function setPurpose(string memory newPurpose) payable public {
      require( msg.value > price, "NOT ENOUGH!");
      purpose = newPurpose;
      // update price when guy set
      price = msg.value;
  }

  function getBalance() view public returns(uint256) {
      return address(this).balance;
  }

  function getMyMoney(address _to, uint256 amount) public {
      	require(msg.sender==owner);
      	address payable receiver = payable(_to);
        receiver.transfer(amount);
  }
}

0x04 Record logs of set purpose by Event

What is an event?

A blockchain is a list of blocks - they are basically made up of transactions. Each transaction has a receipt attached to it, which contains zero or more log entries. These log entries represent the results generated when an event is triggered in a smart contract.

In Solidity source code, to define an event, you need to mark it by prefixing it with the event keyword (similar to the usage of the function keyword). You can then call or trigger the event from within any function that you wish to generate the event. You can trigger events from any function using the emit keyword.

Someone may want to add "listen" for events in the DAPP. It uses the filtering functionality of Web 3.0 (filtering functionality of Web 3.0).

--https://learnblockchain.cn/question/29

We can add event to the setPurpose function to record the history of set purpose.

Translated with www.DeepL.com/Translator (free version)

pragma solidity >=0.8.0 <0.9.0;
//SPDX-License-Identifier: MIT

contract PurposeHandler {

  event SetPurpose(address sender, string purpose);

  string public purpose = "Building Unstoppable Apps";
  address public owner;
  uint256 public price = 0.001 ether;

  constructor(address _owner) {
    owner = _owner;
  }

  function setPurpose(string memory newPurpose) payable public {
      require( msg.value > price, "NOT ENOUGH!");
      purpose = newPurpose;
      // update price when guy set
      price = msg.value;
      emit SetPurpose(msg.sender, purpose);
  }

  function getBalance() view public returns(uint256) {
      return address(this).balance;
  }

  function getMyMoney(address _to, uint256 amount) public {
      	require(msg.sender==owner);
      	address payable receiver = payable(_to);
        receiver.transfer(amount);
  }
}

Summary

That's it for Get & Set value series. Here are all the articles for Get & Set value series.

In the next post, we move on to the next chapter - the design and implementation of the NFT dApp!

Authors:

leeduckgo

msfew