【ブロックチェーン】Truffleの導入とテスト


Truffleの導入とテスト


本文の主な参考:hereとhere、参考したこの文章のバージョンは少し古いので、比較的新しいバージョンに基づいて書いたのです.

一、契約配置


1、まず環境を初期化する
truffle init

2、testrpcを開く
testrpc  // 

3、配置契約
a.契約コードを作成し、contracts/YourContractName.に保存する.solファイル
 :Conference.sol
pragma solidity ^0.4.4;

contract Conference {  // can be killed, so the owner gets sent the money in the end

    address public organizer;
    mapping (address => uint) public registrantsPaid;
    uint public numRegistrants;
    uint public quota;

    event Deposit(address _from, uint _amount); // so you can log the event
    event Refund(address _to, uint _amount); // so you can log the event

    function Conference() {
        organizer = msg.sender;
        quota = 500;
        numRegistrants = 0;
    }

    function buyTicket() payable public {
        if (numRegistrants >= quota) {
            throw; // throw ensures funds will be returned
        }
        registrantsPaid[msg.sender] = msg.value;
        numRegistrants++;
        Deposit(msg.sender, msg.value);
    }

    function changeQuota(uint newquota) public {
        if (msg.sender != organizer) { return; }
        quota = newquota;
    }

    function refundTicket(address recipient, uint amount) public {
        if (msg.sender != organizer) { return; }
        if (registrantsPaid[recipient] == amount) {
            address myAddress = this;
            if (myAddress.balance >= amount) {
                recipient.transfer(amount);
                Refund(recipient, amount);
                registrantsPaid[recipient] = 0;
                numRegistrants--;
            }
        }
        return;
    }

    function destroy() {
        if (msg.sender == organizer) { // without this funds could be locked in the contract forever!
            suicide(organizer);
        }
    }
}

b.既存の2つの契約書類を削除する
MetaCoin.sol   ConvertLib.sol

 : Migrations.sol  

c.migrations/2_の修正deploy_contractsファイル
var Conference = artifacts.require("./Conference.sol");

module.exports = function(deployer) {
  deployer.deploy(Conference);
};

d.コンパイル
truffle compile

e.配置
truffle migrate   truffle migrate --reset

二、テスト


1.test/metacoinを削除する.js
2、conferenceを追加する.jsファイル
a.テスト初期
var Conference = artifacts.require("./Conference.sol");

contract('Conference', function(accounts) {

  var Quato;  // 500
  var NumRegistrants;  // 0
  var Organizer; // 
  var organizer_address = accounts[0];


  it("Initial conference settings should match", function() {

    return Conference.deployed().then(function(instance){
        meta = instance;
        return meta.quota.call();
    }).then(function(quota){
        Quato = quota;
        return meta.organizer.call();
    }).then(function(organizer){
        Organizer = organizer;
        return meta.numRegistrants.call();
    }).then(function(numRegistrants){
        NumRegistrants = numRegistrants;

        assert.equal(Quato, 500, "Quota doesn't match!");
        assert.equal(numRegistrants, 0, "Registrants should be zero!");
        assert.equal(Organizer, organizer_address, "Owner doesn't match!");
    });

  });

});
 :
prodeMacBook-Pro:pc6 pro$ truffle test
Using network 'development'.

Compiling ./contracts/Conference.sol...

Contract: Conference
    ✓ Initial conference settings should match (83ms)

1 passing (107ms)

b.テスト取引
// 
  it("Should let you buy a ticket", function() {

      var user_address = accounts[1];
      var ticketPrice = web3.toWei(.05, 'ether');
      var initialBalance;  // 
      var newBalance;   // 
      var newNumRegistrants;  // 
      var userPaid;  // 
      var difference;

      return Conference.deployed().then(function(instance){
            meta = instance;
            return meta.getBalance.call(user_address);
      }).then(function(balance){
            initialBalance = balance.toNumber();  // 
            return meta.buyTicket({from: user_address, value: ticketPrice});  // 
      }).then(function(){
            return meta.getBalance.call(user_address);
      }).then(function(balance){
            newBalance = balance.toNumber();  // 
            difference = initialBalance - newBalance;
            return meta.numRegistrants.call();
      }).then(function(numRegistrants){
          newNumRegistrants = numRegistrants;
          return meta.registrantsPaid.call(user_address);
      }).then(function(registrantsPaid){
            userPaid = registrantsPaid.toNumber();

            assert.equal(userPaid, ticketPrice, "Sender's paid but is not listed");
            assert.equal(difference, ticketPrice, "Difference should be what was sent");
            assert.equal(newNumRegistrants, 1, "there should be 1 registrant");
      });
  });
 , :

prodeMacBook-Pro:pc6 pro$ truffle test
Using network 'development'.

Compiling ./contracts/Conference.sol...

  Contract: Conference
    ✓ Initial conference settings should match (79ms)
    1) Should let you buy a ticket

    Events emitted during test:
    ---------------------------

    Deposit(_from: 0xd19b5f640c058856bb2f2e2f75454afa2173d2f8, _amount: 50000000000000000)

    ---------------------------

  1 passing (240ms)
  1 failing

  1) Contract: Conference Should let you buy a ticket:
     AssertionError: Difference should be what was sent: expected 56320100000002050 to equal '50000000000000000'
      at test/conference.js:62:20
      at process._tickCallback (internal/process/next_tick.js:109:7)

// 。。 。 。。。