web3.js_1.x.x--API(二)/合约部署与事件调用

Posted on 2018-11-28 15:41  eilinge  阅读(2092)  评论(0编辑  收藏  举报
web3.js_1.x.x的使用和网上查到的官方文档有些不同,我对经常使用到的API进行一些整理,希望能帮到大家
转载博客:http://www.cnblogs.com/baizx/p/7474774.html
pragma solidity ^0.5.0;//指定和solcjs中的solidity编译版本一致

contract MyToken {

    /*
    10000,"eilinge",4,"lin"
    msg.sender:0x14723a09acff6d2a60dcdf7aa4aff308fddc160c
    0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db,20
    0x583031d1113ad414f02576bd6afabfb302140225,40
    0xdd870fa1b7c4700f2bd7f44238821c26f7392148,60

    "0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db","0xdd870fa1b7c4700f2bd7f44238821c26f7392148",10
    */
    /* Public variables of the token */
    string public name;
    string public symbol;
    uint8 public decimals;

    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint)) public allowance;
    mapping (address => mapping (address => uint)) public spentAllowance;

    /* This generates a public event on the blockchain that will notify clients */
    event Transfer(address indexed from, address indexed to, uint256 value);
    event ReceiveApproval(address _from, uint256 _value, address _token, bytes _extraData);

    /* Initializes contract with initial supply tokens to the creator of the contract */
    constructor(uint256 initialSupply, string memory tokenName, uint8 decimalUnits, string memory tokenSymbol) public{
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
        name = tokenName;                                   // Set the name for display purposes
        symbol = tokenSymbol;                               // Set the symbol for display purposes
        decimals = decimalUnits;                            // Amount of decimals for display purposes
    }

    /* Send coins */
    function transfer(address _to, uint256 _value) payable public{
        if (balanceOf[msg.sender] < _value) revert();           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) revert(); // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        emit Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    /* Allow another contract to spend some tokens in your behalf */

    function approveAndCall(address _spender, uint256 _value, bytes memory _extraData)  public returns (bool) {
        allowance[msg.sender][_spender] = _value;
        //emit ReceiveApproval(msg.sender, _value, this, _extraData); //this 在该编译器中无法使用,暂时没有找到正确调用本合约地址
    }

    /* A contract attempts to get the coins */

    function transferFrom(address _from, address _to, uint256 _value) public payable returns(bool) {
        if (balanceOf[_from] < _value) revert();                 // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) revert();  // Check for overflows
        if (spentAllowance[_from][msg.sender] + _value > allowance[_from][msg.sender]) revert();   // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        spentAllowance[_from][msg.sender] += _value;
        emit Transfer(msg.sender, _to, _value);
    }

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () payable external{
        revert();     // Prevents accidental sending of ether
    }
}
solcjs --abi --bin token.sol  -->[eve_sol_MyToken.abi/eve_sol_MyToken.bin]
start truffle:truffle develop //port:9545
var Web3 = require('web3');
var fs = require('fs');
//var web3 = new Web3(new Web3.providers.IpcProvider("\\\\.\\pipe\\geth.ipc",net));
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:9545"));
var eth=web3.eth;

/*
(0) 0x627306090abab3a6e1400e9345bc60c78a8bef57
(1) 0xf17f52151ebef6c7334fad080c5704d77216b732
(2) 0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef
(3) 0x821aea9a577a9b44299b9c15c88cf3087f3b5544
(4) 0x0d1d4e623d10f9fba5db95830f7d3839406c6af2
(5) 0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e
(6) 0x2191ef87e392377ec08e7c08eb105ef5448eced5
(7) 0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5
(8) 0x6330a553fc93768f612722bb8c2ec78ac90b3bbc
(9) 0x5aeda56215b167893e80b4fe645ba6d5bab767de
*/
var abi = JSON.parse(fs.readFileSync("eve_sol_MyToken.abi"));
var bytecode = fs.readFileSync('eve_sol_MyToken.bin');

var tokenContract = new web3.eth.Contract(abi, null, {
    from: '0xf17f52151ebef6c7334fad080c5704d77216b732' // 目前web3没有api来解锁账户,只能自己事先解锁
});

/*
truffle(develop)> tokenContract.options
    { address: [Getter/Setter], jsonInterface: [Getter/Setter] }
truffle(develop)> tokenContract.options.jsonInterface[1]
    { constant: false,
      inputs:
       [ { name: '_from', type: 'address' },
         { name: '_to', type: 'address' },
         { name: '_value', type: 'uint256' } ],
      name: 'transferFrom',
      outputs: [ { name: '', type: 'bool' } ],
      payable: false,
      stateMutability: 'nonpayable',
      type: 'function',
      signature: '0x23b872dd' }
*/
tokenContract.deploy({
    data: bytecode,//bin
    arguments: [32222, 'token on web3',0,'web3']
}).send({
    from: '0xf17f52151ebef6c7334fad080c5704d77216b732',
    gas: 1500000,
    gasPrice: '30000000000000'
}, function(error, transactionHash){
    console.log("deploy tx hash:"+transactionHash)//0xfe4941511eb5155e94843900ff5b489c3b9beca5ac624e31e364637d2bb90bcd
})
.on('error', function(error){
    console.error(error) })
.on('transactionHash', function(transactionHash){
    console.log("hash:",transactionHash)})// 0xfe4941511eb5155e94843900ff5b489c3b9beca5ac624e31e364637d2bb90bcd
.on('receipt', function(receipt){
    console.log(receipt.contractAddress) // contains the new contract address
})
.on('confirmation', function(confirmationNumber, receipt){
    console.log("receipt,",receipt)})
    /*
    receipt, { transactionHash: '0xfe4941511eb5155e94843900ff5b489c3b9beca5ac624e31e364637d2bb90bcd',
      transactionIndex: 0,
      blockHash: '0x97efd68ca1245db9ef6899589e6a3b1b1e404bd08f5f7467896e9d2b4f03a4c0',
      blockNumber: 16,
      gasUsed: 1041001,
      cumulativeGasUsed: 1041001,
      contractAddress: '0x4D2D24899c0B115a1fce8637FCa610Fe02f1909e',
      status: true,
      logsBloom: '0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', events: {} }
*/ .then(function(newContractInstance){ console.log(newContractInstance.options.address) // '0x30753E4A8aad7F8597332E813735Def5dD395028' });
var Web3 = require('web3');
var fs = require('fs');
//var web3 = new Web3(new Web3.providers.IpcProvider("\\\\.\\pipe\\geth.ipc",net));
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:9545"));
var eth=web3.eth;


var MyTokenABI = JSON.parse(fs.readFileSync("eve_sol_MyToken.abi"));
var addr = '0x2C2B9C9a4a25e24B174f26114e8926a9f2128FE4';

var tokenContract = new web3.eth.Contract(MyTokenABI, addr);

//合约部署成功以后,有了地址就可以根据地址来查询合约的状态
tokenContract.methods.name().call(null,function(error,result){
        console.log("contract name "+result);//'token on web3'
    })

    //查询合约状态并不需要发起事务,也不需要花费gas
tokenContract.methods.balanceOf("0xf17f52151ebef6c7334fad080c5704d77216b732").call(null,function(error,result){
        console.log("balanceOf "+result);//387
    })
//调用合约函数:合约的函数除了指明返回值是constant的以外,都需要发起事务,这时候就需要指定调用者,因为要花费该账户的gas.
//查询合约状态并不需要发起事务,也不需要花费gas
tokenContract.methods.transfer("0xf17f52151ebef6c7334fad080c5704d77216b732",387).send({from: '0x627306090abab3a6e1400e9345bc60c78a8bef57'})
.on('transactionHash', function(hash){})
.on('confirmation', function(confirmationNumber, receipt){})
.on('receipt', function(receipt){
    // receipt example
    console.log(receipt); //查询这里可以得到结果
})
.on('error', console.error); // If a out of gas error, the second parameter is the receipt.


//刚刚调用transfer的时候还会触发合约的事件Transfer,如果程序关注谁给谁进行了转账,那么就可以通过监听该事件.
/*tokenContract.events.Transfer({
    fromBlock: 0,
    toBlock:'latest'
},function(error, event){
})
.on('data', function(event){ //Object: 接收到新的事件时触发,参数为事件对象
    console.log(event); // same results as the optional callback above
})
.on('changed', function(event){//Object: 当事件从区块链上移除时触发,该事件对象将被添加额外的属性"removed: true"
    // remove event from local database
})
.on('error', console.error);//Object: 当发生错误时触发
*/
/*
{ transactionHash: '0xb2aff2ac2e95c5f47ca8dc3d97104f0f65346a2c80f5b2dfaa40241276d4110a',
  transactionIndex: 0,
  blockHash: '0x405ce50ab7d02620ae2a61579976ebe5a1a466a13cc03ef857324ac66983ab91',
  blockNumber: 13,
  gasUsed: 36680,
  cumulativeGasUsed: 36680,
  contractAddress: null,
  status: true,
  logsBloom: '0x00000000000000000000000000000000000000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000008000000010000008000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000010000000001000000000010000000000000000000000000000000000000000010000000002000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
  events:
   { Transfer:
      { logIndex: 0,//Number: 事件在块中的索引位置
        transactionIndex: 0,//Number: 事件在交易中的索引位置
        transactionHash: '0xb2aff2ac2e95c5f47ca8dc3d97104f0f65346a2c80f5b2dfaa40241276d4110a',//32 Bytes - String: 事件所在交易的哈希值
        blockHash: '0x405ce50ab7d02620ae2a61579976ebe5a1a466a13cc03ef857324ac66983ab91',//32 Bytes - String: 事件所在块的哈希值,pending的块该值为 null
        blockNumber: 13,//Number: 事件所在块的编号,pending的块该值为null
        address: '0x2C2B9C9a4a25e24B174f26114e8926a9f2128FE4',//String: 事件源地址
        type: 'mined',
        id: 'log_3f0fc629',
        returnValues: [Object],//Object: 事件返回值,例如 {myVar: 1, myVar2: '0x234...'}.
        event: 'Transfer',//String: 事件名称
        signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',//String|Null: 事件签名,如果是匿名事件,则为null
        raw: [Object] } } }
*/

tokenContract.methods.transferFrom('0x627306090abab3a6e1400e9345bc60c78a8bef57',"0xf17f52151ebef6c7334fad080c5704d77216b732",20).send({from: '0x627306090abab3a6e1400e9345bc60c78a8bef57'})
.on('transactionHash', function(hash){})
.on('confirmation', function(confirmationNumber, receipt){})
.on('receipt', function(receipt){
    // receipt example
    console.log(receipt); //查询这里可以得到结果
})
.on('error', console.error);

tokenContract.events.Transfer({
    //fromBlock: 0,
    toBlock:'latest'
},function(error, event){
})
.on('data', function(event){
    console.log(event); // same results as the optional callback above
})
.on('changed', function(event){
    // remove event from local database
})
.on('error', console.error);

/*
Error: Returned error: VM Exception while processing transaction: revert
    at Object.ErrorResponse (C:\Users\wuchan4x\node_modules\web3-core-helpers\src\errors.js:29:16)
    at C:\Users\wuchan4x\node_modules\web3-core-requestmanager\src\index.js:140:36
    at XMLHttpRequest.request.onreadystatechange (C:\Users\wuchan4x\node_modules\web3-providers-http\src\index.js:91:13)
    at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\wuchan4x\node_modules\xhr2-cookies\dist\xml-http-request-event-target.js:34:22)
    at XMLHttpRequest._setReadyState (C:\Users\wuchan4x\node_modules\xhr2-cookies\dist\xml-http-request.js:208:14)
    at XMLHttpRequest._onHttpResponseEnd (C:\Users\wuchan4x\node_modules\xhr2-cookies\dist\xml-http-request.js:318:14)
    at IncomingMessage.<anonymous> (C:\Users\wuchan4x\node_modules\xhr2-cookies\dist\xml-http-request.js:289:61)
    at emitNone (events.js:111:20)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:139:11)
    at process._tickCallback (internal/process/next_tick.js:181:9)
{ transactionHash: '0xe0e37531928e2b0e5592f954dfe6ae8293f28e322d41256b2b64dd80082c93f7',
  transactionIndex: 0,
  blockHash: '0x11b3511ed5269a601af864c74e4946edb56b7ef1f9331868cedf85b7c84cb59e',
  blockNumber: 14,
  gasUsed: 36680,
  cumulativeGasUsed: 36680,
  contractAddress: null,
  status: true,
  logsBloom: '0x00000000000000000000000000000000000000000004000000000000000000000000000,
events: { Transfer: { logIndex: 0, transactionIndex: 0, transactionHash: '0xe0e37531928e2b0e5592f954dfe6ae8293f28e322d41256b2b64dd80082c93f7', blockHash: '0x11b3511ed5269a601af864c74e4946edb56b7ef1f9331868cedf85b7c84cb59e', blockNumber: 14, address: '0x2C2B9C9a4a25e24B174f26114e8926a9f2128FE4', type: 'mined', id: 'log_0f1d28ae', returnValues: [Object], event: 'Transfer', signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', raw: [Object] } } }
*/