智能合约笔记

作者: cowkeys | 来源:发表于2018-08-07 14:12 被阅读1次

    推荐一个入门小教程

    僵尸教程https://cryptozombies.io/

    记录:

    1 错误 栈深溢出

    CompilerError: Stack too deep, try removing local variables.
    

    解决办法:原因是一个function里面的变量 数量不能超过(16),包括了入参和返回值。

    2 货币单位

    一个数字常量(字面量)后面跟随一个后缀wei, finney,szabo或ether,这个后缀就是货币单位。不同的单位可以转换。不含任何后缀的默认单位是wei。
    不同的以太币单位转换关系如下:
    1 ether == 10^3 finney == 1000 finney
    1 ether == 10^6 szabo
    1 ether == 10^18 wei

    3 语法 using ... for ...

    https://ethereum.stackexchange.com/questions/25829/meaning-of-using-safemath-for-uint256

    4 web3.js 监听事件

    (注意 用的是web3.js 1.0 和网上诸多教程 语法不一样)
    Hello.sol:

    //pragma关键字:版本申明。
    //用来指示编译器将代码编译成特定版本,以免引起兼容性问题
    //此处不支持0.4.0之前的编译器,也不支持0.5.0之后的编译器(条件为 ^)
    pragma solidity ^0.4.0;
    //contract关键字:合约申明
    //和Java、PHP中的class类似
    //此处是申明一个名为Hello的合约
    contract Hello {
        event doing(uint  value);
        //public: 函数访问属性(后续文章为详细阐述)
        //returns (string): 定义返回值类型为string
        function say(uint x, uint y) public returns (uint) {
            //var n = bytes(name)
            emit doing(x+y);
            return x+y;
        }
    }
    

    test.js

    //设置web3连接
    var Web3 = require('web3');
    
    var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
    //监听事件一定要用websocket [doc](https://web3js.readthedocs.io/en/1.0/web3.html)
    web3.setProvider('ws://localhost:8546');
    //读取合约
    var fs = require('fs');
    var contractCode = fs.readFileSync('Hello.sol').toString();
    //编译合约代码
    var solc = require('solc');
    var compileCode = solc.compile(contractCode);
    //获取合约abi和字节码
    var abi = JSON.parse(compileCode.contracts[':Hello'].interface);
    //var byteCode = compileCode.contracts[':Hello'].bytecode;
    //合约对象 0x.. 为合约地址
    var myContract = new web3.eth.Contract(abi,'0xD7309ac9B359b1F54CB81Bf7454732029937740E');
    // 执行 node test.js  会一直监听事件
    var event = myContract.events.doing(function (err,result) {
        console.log("Event are as following:-------");
    
        for(let key in result){
            console.log(key + " : " + result[key]);
            console.log(result["returnValues"]);
        }
        console.log("Event ending-------");
    });
    

    5 send 和 transfer 区别

    https://blog.csdn.net/aaa19890808/article/details/79323243

    地址的方法:send():用来向某个地址发送货币(单位为wei)
    
    例子:向地址addr发送100wei
    
              addr=0xqkwjhnckajhsdasdqwe
    
              addr.send(100);
    
    使用send()方法需要注意:
    
    1.调用递归深度不能超过1024
    
    2.gas不足会导致执行失败
    
    3.使用这个方法需要检查成功与否
    
    addr.transfer(10);
    

    send和transfer的区别:
    send方法和transfer很相似,但是比transfer更低级。如果send失败,当前的合约不会中断,也不会抛出异常,会返回一个false。使用send有一些风险:如果调用栈深度超过1024或是gas不够,所有的转让操作都会失败,为了更安全的以太币转移,如果用send就必须每次都要检查返回值,使用transfer方法会更好

    6 view 和 pure 修饰符

    view 修饰的函数 ,只能读取storage变量的值,不能写入。
    pure 修饰的函数 , 不能对storage变量进行读写。

    7 web3.js 中 call 和send 函数区别

    • call is used for view and pure functions. It only runs on the local node, and won't create a transaction on the blockchain. 只能访问 view和pure函数
    • send will create a transaction and change data on the blockchain. You'll need to use send for any functions that aren't view or pure.

    8 web3.js 调用合约 交易

    function createRandomZombie(name) {
            $("#txStatus").text("Creating new zombie on the blockchain. This may take a while...");
            
            return cryptoZombies.methods.createRandomZombie(name)
            .send({ from: userAccount })
            .on("receipt", function(receipt) {
              $("#txStatus").text("Successfully created " + name + "!");
              
              getZombiesByOwner(userAccount).then(displayZombies);
            })
            .on("error", function(error) {
              
              $("#txStatus").text(error);
            });
          }
    

    9 web3.js 监听事件

    - Using indexed 只提醒给当某个地址
    - event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
    #+BEGIN_SRC
    // Use `filter` to only fire this code when `_to` equals `userAccount`
    cryptoZombies.events.Transfer({ filter: { _to: userAccount } })
    .on("data", function(event) {
      let data = event.returnValues;
      // The current user just received a zombie!
      // Do something here to update the UI to show it
    }).on("error", console.error);
    #+END_SRC
    
    - Querying past events
    #+BEGIN_SRC
    cryptoZombies.getPastEvents("NewZombie", { fromBlock: 0, toBlock: "latest" })
    .then(function(events) {
      // `events` is an array of `event` objects that we can iterate, like we did above
      // This code will get us a list of every zombie that was ever created
    });
    #+END_SRC
    

    相关文章

      网友评论

        本文标题:智能合约笔记

        本文链接:https://www.haomeiwen.com/subject/twaovftx.html