如何部署并调用ethereum智能合约

0.本地文件夹 安装 npm install solc web3 fc

0.5 运行testrpc

1. 首先要有一个合约要不输,比如如下合约,保存为文件Token.sol

pragma solidity ^0.4.0;
contract Token {
mapping (address => uint) public balances;

    function Token() {
        balances[msg.sender] = 1000000;
    }

    function transfer(address _to, uint _amount) {
        if (balances[msg.sender] < _amount) {
            throw;
        }

        balances[msg.sender] -= _amount;
        balances[_to] += _amount;
    }
}

2. 用js部署

const fs = require('fs');
const solc = require('solc');
const Web3 = require('web3');
const async = require('async');
const ethabi = require('ethereumjs-abi');
web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
input = fs.readFileSync('Token.sol');
output = solc.compile(input.toString(), 1);
bytecode = output.contracts[':Token'].bytecode;
abi = JSON.parse(output.contracts['Token'].interface);
 function deploy(web3, compiledContract, args, gas, address, sendImmediately) {
  abi = JSON.parse(compiledContract.interface);
  bytecode = compiledContract.bytecode;

  if (args.length > 0) {
    constructTypes = abi
      .filter(x => x.type === 'constructor')[0]
      .inputs.map(x => x.type);
    abiEncoded = ethabi.rawEncode(constructTypes, args);
    console.log(`ABI encoded constructor arguments: ${abiEncoded.toString('hex')}`);
  }

  contract = web3.eth.contract(abi);
  data = `0x${contract.new.getData.apply(null, args.concat({ data: bytecode }))}`;
  if (gas && address && sendImmediately) {
    web3.eth.sendTransaction({ from: address, gas, data }, (err, txHash) => {
      if (err) {
        console.log('err1:', err);
      } else {
        let contractAddress;
        async.whilst(
          () => !contractAddress,
          (callback) => {
            web3.eth.getTransactionReceipt(txHash, (errReceipt, result) => {
              if (result && result.contractAddress) contractAddress = result.contractAddress;
              setTimeout(() => {
                callback(null);
              }, 10 * 1000);
            });
          },
          (errWhilst) => {
            if (!errWhilst) {
              console.log(contractAddress);
            } else {
  console.log('err2:', err);
              console.log(err);
            }
          },
        );
      }
    });
  } else {
    console.log('Contract data:', data);
  }
}
  solidityFile = './Token.sol'
  contractName = 'Token';
  solcVersion = 'v0.4.9+commit.364da425';
  address = web3.eth.coinbase;
  admin = address;
  feeAccount = address;
  accountLevelsAddr = 0;
  feeMake = 0;
  feeTake = 3000000000000000;
  feeRebate = 0;
  gas = 2000000;
  args = [admin, feeAccount, accountLevelsAddr, feeMake, feeTake, feeRebate];
  solc.loadRemoteVersion(solcVersion, (err, solcV) => {
    console.log('Solc version:', solcV.version());/第一遍到这里可能失败,第二次就过去了
    fs.readFile(solidityFile, (errRead, result) => {
      source = result.toString();
      output = solcV.compile(source, 1); // 1 activates the optimiser
      if (output.errors) console.log(output.errors);
      sendImmediately = true;
      deploy(web3, output.contracts[`:${contractName}`], args, gas, address, sendImmediately);//过一会打印部署的合约地址
    });
  });

3.通过abi 接口调用智能合约

得到abi字符串:https://chriseth.github.io/browser-solidity/#version=soljson-latest.js

或者 solcjs --abi  --bin ./token.sol  -o .

abi = JSON.parse('[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balances","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]')

   tokenContract = web3.eth.contract(abi)

   tokenContract = tokenContract.at('0x35877aa1a91a936c52571dad91213fca6b49789f')

   tokenContract.balances(web3.eth.coinbase[0])

   tokenContract.transfer(web3.eth.accounts[1], 222, {from: web3.eth.accounts[0]})

faq:出错处理:

1. gTypeError: Cannot read property 'interface' of undefined
    at deploy (repl:2:43)
    at fs.readFile (repl:10:7)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:528:3)

deploy(web3, output.contracts[`:${contractName}`], args, gas, address, sendImmediately);这里的名称有问题

2.tokenContract.transfer(web3.eth.accounts[3], 999);

    Error: invalid address
    at inputAddressFormatter (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/formatters.js:271:11)
    at inputTransactionFormatter (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/formatters.js:97:20)
    at /home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/method.js:89:28
    at Array.map ()
    at Method.formatInput (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/method.js:88:32)
    at Method.toPayload (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/method.js:114:23)
    at Eth.send [as sendTransaction] (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/method.js:139:30)
    at SolidityFunction.sendTransaction (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/function.js:133:26)
    at SolidityFunction.execute (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/function.js:219:37)

要指定参数:tokenContract.transfer(web3.eth.accounts[4], 999, {from:web3.eth.accounts[3]});

  

你可能感兴趣的:(比特币,智能合约)