区块链大学区块链研习社区块链实践专题

智能合约笔记

2018-08-07  本文已影响1人  cowkeys

推荐一个入门小教程

僵尸教程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 函数区别

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
上一篇下一篇

猜你喜欢

热点阅读