zoukankan      html  css  js  c++  java
  • 合约实战,代币合约,DAPP开发

    1. ERC20标准

    https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md

    pragma solidity ^0.4.4;
    
    //定义接口
    contract ERC20Interface{
      string public name;
      string public symbol;
      uint8 public decimals;
      uint256 public totalSupply;
    
      /* function balanceOf(address _owner) view returns (uint256 balance); */
      function transfer(address _to, uint256 _value) returns (bool success);
      function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
      function approve(address _spender, uint256 _value) returns (bool success);
      function allowance(address _owner, address _spender) view returns (uint256 remaining);
    
      event Transfer(address indexed _from, address indexed _to, uint256 _value);
      event Approval(address indexed _owner, address indexed _spender, uint256 _value);
    
    }
    
    contract ERC20 is ERC20Interface{
      mapping(address => uint256) public balanceOf;
      //委托,允许他人操作的金额数
      mapping(address => mapping(address => uint256)) allowed;
    
      //构造方法
      constructor() public {
        name = "MyToken";
        symbol = "weixuexi";
        decimals = 0;
        totalSupply = 10000;
        balanceOf[msg.sender] = totalSupply;
      }
    
      /* function balanceOf(address _owner) view returns (uint256 balance){
        return balanceOf[_owner];
      } */
      function transfer(address _to, uint256 _value) returns (bool success){
        require(_to != address(0));
        require(balanceOf[msg.sender] >= _value);
        require(balanceOf[_to] + _value > balanceOf[_to]);
    
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        emit Transfer(msg.sender, _to, _value);
      }
      function transferFrom(address _from, address _to, uint256 _value) returns (bool success){
    
        require(_from != address(0));
        require(_to != address(0));
        require(balanceOf[_from] >= _value);
        require(allowed[msg.sender][_from] >= _value);  //当前合约能操作_from的钱数要大于_value
        require(balanceOf[_to] + _value > balanceOf[_to]);
    
        balanceOf[_from] -= _value;
        balanceOf[_to] += _value;
        emit Transfer(_from, _to, _value);
    
        success = true;
      }
      function approve(address _spender, uint256 _value) returns (bool success){
        //当前账户允许—_spender操作的金额数
        allowed[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        success = true;
      }
      function allowance(address _owner, address _spender) view returns (uint256 remaining){
        return allowed[_owner][_spender];
      }
    }
    View Code

     2.DAPP去中心化应用开发【web项目】

      web3.js

      solidity

      truffle  https://truffleframework.com/docs/truffle/getting-started/installation

      ganache

    开发流程:

    • 新建项目【初始化】
    • 编写合约
    • 合约编译、部署、测试
    • 与合约交互

    安装truffle:

    npm install -g truffle
    查看版本:truffle.cmd version

    创建项目:

      下载基本文件:

          cd pet-shop

        truffle init  【安装项目】

      下载pet-shop包文件:

        cd pet-shop

        truffle unbox pet-shop

     编写智能合约:Adoption.sol

    pragma solidity ^0.4.23;
    
    
    contract Adoption {
        address[16] public adoptors; //领养这地址
    
        function adopt(uint petId) public returns(uint) {
            adoptors[petId] = msg.sender;
            return petId;
        }
    
        function getAdoptors() public view returns (address[16]) {
            return adoptors;
        }
    }

    编译: truffle.cmd compile【方式一,结合使用ganache】

      truffle develop 【方式二,truffle集成了testrpc】; compile;

    部署合约:migrate

      部署合约脚本: 1_migration.js   改文件用于监听合约文件的动向,是否更新,变化

    var MyContract = artifacts.require("MyContract");
    
    module.exports = function(deployer) {
      // deployment steps
      deployer.deploy(MyContract);
    };

       truffle.js:

    module.exports = {
      // See <http://truffleframework.com/docs/advanced/configuration>
      // to customize your Truffle configuration!
      networks: {
        development: {
          host: "127.0.0.1",  //主机
          port: 7545,  //端口,和ganache对应
          network_id: "*" // Match any network id
        }
      }
    };

      部署合约:[truffle] migrate

    输出结果:Adoption.json  [编译出的文件做出了更新]

     这时,ganache中可以发现,已经出来了4个区块:

    还有交易信息:

     获取合约实例,调用函数:

    pragma solidity ^0.4.23;
    
    contract Hello {
        //如果使用pure修饰,可以通过合约对象直接调用,否则需要使用call方法调用
        function test() pure public returns (string) {
            return "hello world";
        }
    }
    Hello.sol

    /migrations/3_deploy_hello.js

    var Hello = artifacts.require("./Hello.sol");
    
    module.exports = function(deployer) {
      deployer.deploy(Hello);
    };

      使用web3获取合约实例: 

    >truffle: let contract;   //声明contract变量

        contract = Hello.deployed().then(instance => contract=instance)             //Hello 是上面迁移文件的合约实例

    pragma solidity ^0.4.23;
    
    import "truffle/Assert.sol";
    import "truffle/DeployedAddresses.sol";
    import "../contracts/Adoption.sol";
    
    contract TestAdoption {
        Adoption adoption = Adoption(DeployedAddresses.Adoption());
    
        function testUserCatAdoptPet() public {
            uint returnId = adoption.adopt(8);
    
            uint expect = 8;
            Assert.equal(returnId, expect, "Adoption of pet Id 8 should be recorded");
        }
    
        function testGetAdoptorAddByPetId() public {
            address expect = this;
            address adoptor = adoption.adoptors(8);
            Assert.equal(expect, adoptor, "get adopt by pet id");
        }
    }
    View Code

      注意:修改完合约文件后,重新编译【compile】后,重新部署命令【migrate --reset】

      调用合约方法:contract.test();

       使用断言测试:Assert

    同时会多出很多新的区块和交易

     3.web3.js api的使用

    官网

      进入truffle开发环境:truffle.cmd develop

      获取账户余额:web3.eth.getBalace("").toString();

    truffle(develop)> web3.eth.getBalance("0x627306090abab3a6e1400e9345bc60c78a8bef57").toString()
       '100000000000000000000'

      获取所有账户:web3.eth.accounts;

    truffle(develop)> null [ 
      '0x627306090abab3a6e1400e9345bc60c78a8bef57',
      '0xf17f52151ebef6c7334fad080c5704d77216b732',
      '0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef',
      '0x821aea9a577a9b44299b9c15c88cf3087f3b5544',
      '0x0d1d4e623d10f9fba5db95830f7d3839406c6af2',
      '0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e',
      '0x2191ef87e392377ec08e7c08eb105ef5448eced5',
      '0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5',
      '0x6330a553fc93768f612722bb8c2ec78ac90b3bbc',
      '0x5aeda56215b167893e80b4fe645ba6d5bab767de' ]

      获取当前账号:【数组中的第0个账号】

    truffle(develop)> web3.eth.coinbase;
      '0x627306090abab3a6e1400e9345bc60c78a8bef57'

       web3.fromWei(num, 单位);

    truffle(develop)> web3.fromWei(5, 'ether')
        '0.000000000000000005'

      web3.toWei(num,单位)

      默认的区块:

    truffle(develop)> web3.eth.defaultBlock
      'latest'

      交易:

    truffle(develop)> web3.eth.sendTransaction({from:account1, to:account2, value:100000000000000000})
      '0xb5065a9a03d75f08d7e704d352d08de5c8c4f8f19cc654cb1261d254f6194d90'
    truffle(develop)> web3.eth.getBalance(account1)
      BigNumber { s: 1, e: 19, c: [ 998999, 99999999979000 ] }
    truffle(develop)> web3.eth.getBalance(account2)
      BigNumber { s: 1, e: 20, c: [ 1001000 ] }
    truffle(develop)> web3.eth.getBalance(account1).toString()
      '99899999999999979000'
    truffle(develop)> web3.eth.getBalance(account2).toString()
      '100100000000000000000'
    truffle(develop)> web3.fromWei(web3.eth.getBalance(account1).toString(), 'ether')
      '99.899999999999979'
    truffle(develop)> web3.fromWei(web3.eth.getBalance(account2).toString(), 'ether')
      '100.1'
    truffle(develop)> web3.fromWei(web3.eth.getBalance(web3.eth.accounts[2]).toString(), 'ether')
      '100'

      

    4. 代币合约的概念

    pragma solidity ^0.4.4;
    
    contract EncryptedToken {
        uint256 INITAL_SUPPLY = 10000;
        mapping(address => uint) public balanceOf;
        constructor() {
            balanceOf[msg.sender] = INITAL_SUPPLY;
        }
        function transfer(address _to, uint256 _value) public {
            require(_to != address(0));
            require(balanceOf[msg.sender] >= _value);
            require(balanceOf[_to] + _value > balanceOf[_to]);
    
            balanceOf[msg.sender] -= _value;
            balanceOf[_to] += _value;
        }
    }
    EncryptedToken.sol
    var EncryptedToken = artifacts.require("./EncryptedToken.sol");
    
    module.exports = function(deployer) {
      deployer.deploy(EncryptedToken);
    };
    1_deploy_encryptedToken.js

    部署:

      truffle.cmd develop

      compile

      migate

      let c;

      EncryptedToken.deployed().then(inc => c=inc);

      c.balanceOf("0x627306090abab3a6e1400e9345bc60c78a8bef57") ;  ->10000   //钱包地址

    默认部署到第一个测试钱包中:

    转账:c.transfer("0xf17f52151ebef6c7334fad080c5704d77216b732",1000)

    truffle(develop)> c.balanceOf("0x627306090abab3a6e1400e9345bc60c78a8bef57")
           BigNumber { s: 1, e: 3, c: [ 9000 ] }

    5. web端

    4.1 使用npm管理项目

      npm init

      安装web server:npm install lite-server

    配置文件:bs-config.json

    {
        "server" : {
            "baseDir":["./src", "./build/contracts"]
        }
    }

    package.json:

    启动服务:npm run dev

  • 相关阅读:
    MFC函数—SetRegistryKey
    2013年日志及2014年、2012年等一些日志
    DECLARE_MESSAGE_MAP 宏
    c++ 重载、覆盖 (隐藏)(virtual)
    //{{AFX_MSG、//{{AFX_VIRTUAL、//{{AFX_MSG_MAP、//{{AFX_DATA_INIT
    #if defined 和 #if ! defined 的用法
    C++标准模板库STL
    C++标准库
    C++中的 CONST 含义(从#define 到 CONST 的转变)
    More Effective C++ 35 条款
  • 原文地址:https://www.cnblogs.com/zhuxiang1633/p/9486914.html
Copyright © 2011-2022 走看看